请教一个查询账龄的SQL,非常感谢回答。

t_item 2008-07-29 03:26:21
如何写个查询语句计算账龄?
有这么一个表:


产品 年 月 期初 购入 发出 期末
A 2008 1 0 10 5 5
A 2008 2 5 20 2 23
A 2008 3 23 20 0 43
A 2008 4 43 30 10 63



以最后一期期末时间(2008年4月30日)为基准,按先进先出法分析期末账龄:

这样理解,先购进的先出:

2008年1月末的5台是1月购入,
2月的23台有3台是1月、20台是2月,
3月的43台有3台是1月、20台是2月、20台是3月,
4月末的63台有13台是2月、20台是3月、30台是4月

最终得到下表:

产品 期末库存 账龄1个月内的库存 账龄1-2个月 账龄2-3个月 账龄>3个月
A 63 30 20 13 0
...全文
741 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdxiong 2008-07-31
  • 打赏
  • 举报
回复
如果是负数,可以把购入当成是发出,而发出就当成是购入

把最内层的Select修改一下就可以了
sdxiong 2008-07-30
  • 打赏
  • 举报
回复
我真笨....原来还有更好的方法


declare @t table (产品 char(1),年 int,月 int,期初 int,购入 int,发出 int,期末 int)
insert into @t
select 'A', 2008, 1, 0, 10, 5, 5 union
select 'A', 2008, 2, 5, 20, 2, 23 union
select 'A', 2008, 3, 23, 20, 0, 43 union
select 'A', 2008, 4, 43, 30, 10, 63 union
select 'B', 2008, 1, 0, 10, 5, 5 union
select 'B', 2008, 2, 5, 20, 2, 23 union
select 'B', 2008, 3, 23, 20, 0, 43 union
select 'B', 2008, 4, 43, 30, 10, 63

declare @ym datetime
set @ym = '2008-04-30' --期未

select 产品,期末库存,
case when 账龄1个月内的库存>0 then 账龄1个月内的库存 else 0 end as 账龄1个月内的库存,
case when 账龄1到2个月 >0 then 账龄1到2个月 else 0 end as 账龄1到2个月,
case when 账龄2到3个月 >0 then 账龄2到3个月 else 0 end as 账龄2到3个月,
case when 账龄大于3个月>0 then 账龄大于3个月 else 0 end as 账龄大于3个月
from (
select 产品,期末库存,
case when 期末库存>一月内购 then 一月内购 else 期末库存 end as 账龄1个月内的库存,
case when 期末库存-一月内购>一月前购 then 一月前购 else 期末库存-一月内购 end as 账龄1到2个月,
case when 期末库存-一月内购-一月前购>二月前购 then 二月前购 else 期末库存-一月内购-一月前购 end as 账龄2到3个月,
case when 期末库存-一月内购-一月前购-二月前购>三月前购 then 三月前购 else 期末库存-一月内购-一月前购-二月前购 end as 账龄大于3个月
from (
select 产品,
sum(case when datediff(mm,年月,@ym)=0 then 期末 else 0 end) as 期末库存,
sum(case when datediff(mm,年月,@ym)=0 then 购入 else 0 end) as 一月内购,
sum(case when datediff(mm,年月,@ym)=1 then 购入 else 0 end) as 一月前购,
sum(case when datediff(mm,年月,@ym)=2 then 购入 else 0 end) as 二月前购,
sum(case when datediff(mm,年月,@ym)>2 then 购入 else 0 end) as 三月前购
from (select *,cast(年 as varchar(4))+'-'+cast(月 as varchar(2))+'-1' as 年月 from @t) a
group by 产品
) b
) c

/*
产品 期末库存 账龄1个月内的库存 账龄1到2个月 账龄2到3个月 账龄大于3个月
---- ----------- --------------- ----------- ----------- -----------
A 63 30 20 13 0
B 63 30 20 13 0

(所影响的行数为 2 行)
*/
t_item 2008-07-30
  • 打赏
  • 举报
回复
谢谢。
我测试了一下。
如果购入和发出是负数的情况,结果就会不一致。
能否完善一下?
谢谢。
sdxiong 2008-07-29
  • 打赏
  • 举报
回复

declare @t table (产品 char(1),年 int,月 int,期初 int,购入 int,发出 int,期末 int)
insert into @t
select 'A', 2008, 1, 0, 10, 5, 5 union
select 'A', 2008, 2, 5, 20, 2, 23 union
select 'A', 2008, 3, 23, 20, 0, 43 union
select 'A', 2008, 4, 43, 30, 10, 63 union
select 'B', 2008, 1, 0, 10, 5, 5 union
select 'B', 2008, 2, 5, 20, 2, 23 union
select 'B', 2008, 3, 23, 20, 0, 43 union
select 'B', 2008, 4, 43, 30, 10, 63

declare @ym datetime
set @ym = '2008-04-30' --期未

select 产品,
sum(case when datediff(mm,年月,@ym)=0 then 期末 else 0 end) as 期未库存,
sum(case when datediff(mm,年月,@ym)=0 then case when 总发出+发出>=累计购入+购入 then 0
else case when 累计购入>=总发出 then 购入
else 购入-(总发出-累计购入)
end
end
else 0
end) as 账龄1个月内的库存,
sum(case when datediff(mm,年月,@ym)=1 then case when 总发出+发出>=累计购入+购入 then 0
else case when 累计购入>=总发出 then 购入
else 购入-(总发出-累计购入)
end
end
else 0
end) as 账龄1到2个月,
sum(case when datediff(mm,年月,@ym)=2 then case when 总发出+发出>=累计购入+购入 then 0
else case when 累计购入>=总发出 then 购入
else 购入-(总发出-累计购入)
end
end
else 0
end) as 账龄2到3个月,
sum(case when datediff(mm,年月,@ym)>2 then case when 总发出+发出>=累计购入+购入 then 0
else case when 累计购入>=总发出 then 购入
else 购入-(总发出-累计购入)
end
end
else 0
end) as 账龄大于3个月
from
(
select a.产品,cast(a.年 as varchar(4))+'-'+cast(a.月 as varchar(2))+'-1' as 年月,
a.期初,a.购入,a.发出,a.期末,sum(isnull(b.购入,0)) as 累计购入,c.总发出
from @t a
left join @t b on a.产品=b.产品 and
cast(a.年 as varchar(4))+'-'+cast(a.月 as varchar(2))>cast(b.年 as varchar(4))+'-'+cast(b.月 as varchar(2))
left join (select 产品,sum(发出) as 总发出
from @t
where cast(年 as varchar(4))+'-'+cast(月 as varchar(2))+'-1'<=@ym
group by 产品
) c on a.产品=c.产品
group by a.产品,a.年,a.月,a.期初,a.购入,a.发出,a.期末,c.总发出
) d
where 年月<=@ym
group by 产品

/*
产品 期未库存 账龄1个月内的库存 账龄1到2个月 账龄2到3个月 账龄大于3个月
---- ----------- ----------- ----------- ----------- -----------
A 63 30 20 13 0
B 63 30 20 13 0

(所影响的行数为 2 行)
*/

t_item 2008-07-29
  • 打赏
  • 举报
回复
▉▉▉╱◢▉◣◢▉◣◥◣╱◢◤╱╱╱╱╱╱╱
╱▉╱╱▉U◥◤K▉╱◥▉◤╱◢▉◣╱▉╱▉
╱▉╱╱◥◣小熊◢◤╱╱▉╱╱▉╱▉╱▉╱▉
╱▉╱╱╱◥◣◢◤╱╱╱▉╱╱▉╱▉╱▉╱▉
▉▉▉╱╱╱◥◤╱╱╱╱▉╱╱◥▉◤╱◥▉◤

t_item 2008-07-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 Shellbkboy 的回复:]
说实话看不懂 1月0+10-5=5 2月5+20-2=23 .。。。。。依次 真不知道你的3台是一月的怎么算的 为什么20台是2月的 依次后面的都看不懂 最后末期库存30怎么计算的?
[/Quote]
先购进的先出。
比如
一月,期初为0,购进10台,卖5台,剩下5台就是一月的。
二月,期初5台是上月的,本月购进20,本月卖2台(这两台卖的是上月剩下的5台中的两台),剩下23台有3台是1月、20台是2月
三月,期初23台(3台是1月、20台是2月),本月购进20,卖0台,剩下43台就是3台是1月、20台是2月、20台是本月
四月,期初43台(3台是1月、20台是2月、20台是3月),本月购进30,卖10台(这10台中3台是1月的那3台,7台是2月20台中的7台),那么最后库存的63台(就是2月13台,3月20台,4月30台)
Shellbkboy 2008-07-29
  • 打赏
  • 举报
回复
说实话看不懂 1月0+10-5=5 2月5+20-2=23 .。。。。。依次 真不知道你的3台是一月的怎么算的 为什么20台是2月的 依次后面的都看不懂 最后末期库存30怎么计算的?



22,294

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧