简化SQL表的查询,每月12列

时间:2010-01-29 20:13:14

标签: sql sql-server sql-server-2000

我有一张桌子,每个月有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会派上用场。

7 个答案:

答案 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'