我有一张桌子,每个月有12列。我需要创建一个SP,在其中传入productID,Customer和Month参数并检索该月的总和。
目前我的逻辑是
if month = 1 then
select sum(JAN) from table where productID = @id and customer = @cust
if month = 2 then
select SUM(FEB) from table where productID = @id and customer = @cust
....
查询涉及更多,但这是它的核心。这些“IF”声明有什么办法吗?
编辑 - 这是一个SQL Server 2000数据库,但将迁移到SQL Server 2005,当我迁移到SQL Server 2005时,PIVOT和UNPIVOT会派上用场。
答案 0 :(得分:8)
我认为查询的难度源于您的数据库未正确规范化的事实。
您似乎有一个包含列的表:
productId
customer
JAN
FEB
...
在存储过程中,您创建了一个看起来像这样的临时表。这不是在SQL中执行此操作的最佳方法。你的目标应该是像你的表结构那样:
productId
customer
date
amount
然后,您可以使用简单的WHERE子句编写查询:
SELECT SUM(amount)
FROM table
WHERE MONTH(date) = month AND productID = @id and customer = @cust
您可能还想检查查询中的年份,否则您可能会对2009年1月和2010年1月的数据进行求和。或者......也许您每年都有一张桌子? (我希望不是!)
注意:当然,此时可能无法更改表结构。我还是觉得如果你不知道这个问题,这值得一提。至少知道这一点可能会防止将来再犯同样的错误。
答案 1 :(得分:6)
查看UNPIVOT
- 您可以忽略将列设置为行,然后使用WHERE
子句仅获取您感兴趣的月份的行。
内部:
SELECT *
FROM tbl UNPIVOT FOR Month IN ([JAN], [FEB], etc...)
然后加入表格将月份翻译为数字: 1月1日 2月2日 ETD。
然后WHERE MonthNum = @param
答案 2 :(得分:3)
怎么样:
declare @month int
set @month = 2
select sum(case @month
when 1 then JAN
when 2 then FEB
when 3 then MAR
when 4 then APR
when 5 then MAY
when 6 then JUN
when 7 then JUL
when 8 then AUG
when 9 then SEP
when 10 then OCT
when 11 then NOV
when 12 then DEC
else 0
end)
from table
where productID = @id
and customer = @cust
答案 3 :(得分:3)
select sum(case when @month = 1 then Jan
when @month = 2 then Feb
when @month = 3 then Mar
when @month = 4 then Apr
when @month = 5 then May
when @month = 6 then Jun
when @month = 7 then Jul
when @month = 8 then Aug
when @month = 9 then Sep
when @month = 10 then Oct
when @month = 11 then Nov
when @month = 12 then [Dec] end)
from mytable
where productID = @id and customer = @cust
假设您声明并初始化变量,这应该有效。当然,如果你想做多个月,那就更复杂了,这就是为什么设计不适合查询的原因之一。
答案 4 :(得分:1)
首先想到的是 - 您可以使用动态sql生成查询,并使用简单的EXEC
执行。
这听起来像是一个没有麻烦的解决方案,对于这么简单的查询,我没有理由不选择最简单的选项。
答案 5 :(得分:1)
您可以查看SQL Server中的UNPIVOT函数 - UnPivot
答案 6 :(得分:0)
select sum(quantity) from table unpivot (quantity for month in (jan,feb,mar/*etc*/)) as t where where productID = @id and customer = @cust and month='jan'