使用T-SQL构建去年的客户报告

时间:2015-07-02 16:36:32

标签: sql sql-server tsql

我有3张桌子(简化):

-----------Orders--------------------
Id | Total_Price | Customer_Id | Date

--------Order Details---------------------
Id | Order_Id | Product Name | Qty | Value

----Customers------
Id | Name | Address

我使用此查询获取单个客户的总订单价值:

SELECT C.ID, C.NAME , SUM(O.TOTAL_PRICE)
FROM CUSTOMERS C
JOIN ORDERS O ON O.CUSTOMER_ID = C.ID
GROUP BY C.ID, C.NAME

现在,我想构建一个报告,其总订单价值按一系列日期过滤:

SELECT C.ID, C.NAME , SUM(O.TOTAL_PRICE)
FROM CUSTOMERS C
JOIN ORDERS O ON O.CUSTOMER_ID = C.ID
WHERE O.DATE BETWEEN @value1 AND @value2
GROUP BY C.ID, C.NAME

这样可行,但我想选择按客户分组的总订单价值的最后3年总和,这是我想要的结果:

        1Year | 2Year | 3Year | Customer_Name
    ------------------------------------------------- 
        XXX   | YYY   | ZZZZ  | Customer1
        XYX   | YYZ   | ZZTZ  | Customer2
....

我有这个基数: 客户表有22.000行 订单表有87.000行 订购详情600.000

没有具有较长执行时间的temptable,vartable或存储过程是否可行?

在我的报告中,我还要计算按产品客户分组的过去3年的总数量,但这是下一步。 有任何想法吗? 感谢

2 个答案:

答案 0 :(得分:3)

您可以使用案例陈述来获得所需的结果。由于你的帖子中有关于如何定义年份范围的含糊不清,我已经遗漏了任何计算以获得那些年末/开始并且只是将变量放入。你可以修改以满足你的需要。

SELECT C.ID
    ,C.NAME
    ,SUM(CASE 
            WHEN o.DATE BETWEEN @year1start
                    AND @year1end
                THEN O.TOTAL_PRICE
            ELSE 0
            END) Year1
    ,SUM(CASE 
            WHEN o.DATE BETWEEN @year2start
                    AND @year2end
                THEN O.TOTAL_PRICE
            ELSE 0
            END) Year2
    ,SUM(CASE 
            WHEN o.DATE BETWEEN @year3start
                    AND @year3end
                THEN O.TOTAL_PRICE
            ELSE 0
            END) Year3
FROM CUSTOMERS C
INNER JOIN ORDERS O ON O.CUSTOMER_ID = C.ID
GROUP BY C.ID
    ,C.NAME

答案 1 :(得分:1)

另一种选择是使用pivot语句。我假设您的每个日期范围等于一年(例如2013年,2014年等) 如果强烈确定这些年份,那么选择(look at full sqlfiddle example, it has possible solution for your additional question

是非常漂亮的选择
select
    c.Id, c.Name, c.Address, CostByYear.[2013], CostByYear.[2014], CostByYear.[2015]
from Customers c
left join (
    select
        pt.Customer_Id, isnull(pt.[2013], 0) as [2013], 
        isnull(pt.[2014], 0) as [2014], isnull(pt.[2015], 0) as [2015]
    from (
        select
            o.Customer_Id, year(o.Date) [Year], sum(o.Total_Price) [TotalCost]
        from Orders o
        group by
            o.Customer_Id, year(o.Date)
    ) src
    pivot (
        sum(TotalCost) for [Year] in ([2013], [2014], [2015])
    ) pt
) CostByYear on
    c.Id = CostByYear.Customer_Id
order by
    c.Name

如果年份范围未知并且定义明确,您也可以使用动态创建的查询执行这两种方法(我的和普通答案)。