注册 登录
编程论坛 SQL Server论坛

求 帐龄分析SQL语句

jockey 发布于 2007-11-30 09:50, 3216 次点击
帐龄分析

表结构及记录如下

Tb

名称       时间            金额
张三      2007.1.1       100
张三      2007.10.30   200
张三      2006.5.12     400
马六      2007.11.5     150
王五      2005.10.1      900

要求实现下表:

名称    3个月以内     3个月-1年      1年以上      合计
张三       200              100                 400         700
马六       150                                                     150
王五                                                  900          900
25 回复
#2
purana2007-11-30 10:05
declare @t table(名称 varchar(10),时间 datetime,金额 int)
insert @t select '张三','2007-1-1',100
union all select '张三','2007-10-30',200
union all select '张三','2006-5-12',400
union all select '马六','2007-11-5',150
union all select '王五','2005-10-1',900

select 名称,
    [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end),
    [三个月到一年]=sum(case when datediff(month,时间,getdate())>3 and datediff(month,时间,getdate()) <=12 then 金额 else 0 end),
    [一年以上]=sum(case when datediff(month,时间,getdate())>12 then 金额 else 0 end),
    [合计]=sum(金额)
from @t
group by 名称
order by 名称

/*
名称         三个月以内       三个月到一年      一年以上        合计         
---------- ----------- ----------- ----------- -----------
马六         150         0           0           150
王五         0           0           900         900
张三         200         100         400         700

(所影响的行数为 3 行)
/*
#3
XieLi2007-11-30 10:17
又比我快!
#4
purana2007-11-30 10:19
我要加速度..
#5
jockey2007-11-30 10:45
高手就是高手!感谢啊!

老大,再帮忙看看:
因为记录有正数有负数,而合计可能为0
我想让合并后的 合计为0的就不显示了。如何弄?
#6
jockey2007-11-30 10:46
[合计]=sum(金额) 可能为0,想让最后的结果中 [合计]=0的不显示
#7
XieLi2007-11-30 10:51
select 名称,
    [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end),
    [三个月到一年]=sum(case when datediff(month,时间,getdate())>3 and datediff(month,时间,getdate()) <=12 then 金额 else 0 end),
    [一年以上]=sum(case when datediff(month,时间,getdate())>12 then 金额 else 0 end),
    [合计]=sum(金额)
from @t

group by 名称 having sum(金额)<>0
order by 名称

[[italic] 本帖最后由 XieLi 于 2007-11-30 10:53 编辑 [/italic]]
#8
jockey2007-11-30 10:54
真的很感谢版主和XieLi
#9
purana2007-11-30 10:57
刚转了一下..晚了..
#10
XieLi2007-11-30 10:58
下次留给你!
#11
jockey2007-11-30 11:20
下次的机会来了

问题:
另外一个表为
TB_2
名称   描述
张三   大学
王二   中学
马六   小学

现在要在干才那个表的基础上,加上 描述 字段:

名称  描述       三个月以内       三个月到一年      一年以上        合计         
---------- ----------- ----------- ----------- -----------
马六  小学       150         0           0           150
王五  中学       0           0           900         900
张三  大学       200         100         400         700
#12
jockey2007-11-30 11:22
我在后面加上
   ...Tb_2.描述.... LEFT JOIN Tb_2  ON Tb.名称=Tb_2.名称

提示语法错误
#13
purana2007-11-30 11:29
declare @t table(名称 varchar(10),时间 datetime,金额 int)
insert @t select '张三','2007-1-1',100
union all select '张三','2007-10-30',200
union all select '张三','2006-5-12',400
union all select '马六','2007-11-5',150
union all select '王五','2005-10-1',900

declare @t2 table(名称 varchar(10),描述 varchar(10))
insert @t2 select '张三','大学'
union all select '王五','中学'
union all select '马六','小学'

select a.名称,b.描述,a.[三个月以内],a.[三个月到一年],a.[一年以上],a.[合计]
from
(
    select 名称,
        [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end),
        [三个月到一年]=sum(case when datediff(month,时间,getdate())>3 and datediff(month,时间,getdate()) <=12 then 金额 else 0 end),
        [一年以上]=sum(case when datediff(month,时间,getdate())>12 then 金额 else 0 end),
        [合计]=sum(金额)
    from @t
    group by 名称
) a
left join @t2 b
on a.名称=b.名称
order by a.名称

/*
名称         描述         三个月以内       三个月到一年      一年以上        合计         
---------- ---------- ----------- ----------- ----------- -----------
马六         小学         150         0           0           150
王五         中学         0           0           900         900
张三         大学         200         100         400         700

(所影响的行数为 3 行)
*/
#14
XieLi2007-11-30 11:36
给你啦!
#15
jockey2007-11-30 13:12
感谢两位!
我发现个问题:

select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称

就要出错!
而去掉 编号
可以正常,也就是group by 只允许 一个字段
#16
XieLi2007-11-30 13:33
select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称,编号

去帮助里查一下GROUP BY 的用法
#17
purana2007-11-30 14:19
这是Group by 句法的问题...
同意楼上说在帮助查一下..

但是你这种句法.
select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称

...在SQL2003标准中是可以的.因为它会自动查找函数依赖..
但是现在还没有数据库产品支持SQL2003标准.
#18
XieLi2007-11-30 14:25
SQL2003没用过呢?
现在不是有SQL2005吗好用吗?
#19
缘吇弹2007-11-30 14:34
哈哈。。。SQL区因你们而活跃啊。
#20
缘吇弹2007-11-30 14:35
原帖由 [bold][underline]XieLi[/underline][/bold] 于 2007-11-30 14:25 发表 [url=http://bbs.bc-cn.net/redirect.php?goto=findpost&pid=1124227&ptid=189454][/url]
SQL2003没用过呢?
现在不是有SQL2005吗好用吗?

我也没用过。
#21
XieLi2007-11-30 14:39
原帖由 [bold][underline]缘吇弹[/underline][/bold] 于 2007-11-30 14:35 发表 [url=http://bbs.bc-cn.net/redirect.php?goto=findpost&pid=1124240&ptid=189454][/url]

我也没用过。


是哦,什么用一下.

[bold][underline]缘吇弹哥哥,这几天可没有看到你哦![/underline][/bold]
#22
purana2007-11-30 14:47
原帖由 [bold][underline]XieLi[/underline][/bold] 于 2007-11-30 14:25 发表 [url=http://bbs.bc-cn.net/redirect.php?goto=findpost&pid=1124227&ptid=189454][/url]
SQL2003没用过呢?
现在不是有SQL2005吗好用吗?


我说的是SQL标准..
不是SQLServer产品.
#23
purana2007-11-30 14:49
SQL2003标准是SQL标准组织在2003年发布的一个新的标准..对SQL1999进行了扩充..其中之一就是上面所说的..
#24
jockey2007-11-30 15:25
#25
madpbpl2007-12-01 01:22
原帖由 [bold][underline]jockey[/underline][/bold] 于 2007-11-30 13:12 发表 [url=http://bbs.bc-cn.net/redirect.php?goto=findpost&pid=1124098&ptid=189454][/url]
感谢两位!
我发现个问题:

select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())


select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称
就要出错!
而去掉 编号
可以正常,也就是group by 只允许 一个字段



就拿这个例子作为我开始进入sql server版块学习的标记点吧。
我只会acc,但是感觉在sql语句上和sql server类似。
对于以下这种情况

select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称
就要出错!
而去掉 编号
可以正常,也就是group by 只允许 一个字段

可以采用以下方式来解决
select 名称,编号, [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称,编号
但是上面这种方法可能会发现不能去除重复记录
那么可以采用如下方式来测试
select 名称,min(编号), [三个月以内]=sum(case when datediff(month,时间,getdate())<=3 then 金额 else 0 end) from Tb group by 名称
这种写法是针对acc的,对于sql server不知道是否适用
向楼上各位高手学习,年底初步掌握sql server
#26
缘吇弹2008-01-22 10:28
原帖由 [bold][underline]XieLi[/underline][/bold] 于 2007-11-30 14:39 发表 [url=http://bbs.bccn.net/redirect.php?goto=findpost&pid=1124245&ptid=189454][/url]


是哦,什么用一下.

缘吇弹哥哥,这几天可没有看到你哦!


前些天在忙些东西,所以。。。。
不过现在好了,放假了。呵呵
1