在单个选择语句中计数多个时间范围内的订单数

时间:2013-09-12 13:38:59

标签: sql tsql date count

提前感谢任何想法,建议和建议!

系统:SQL Server 2008 R2

我需要为给定客户计算几个不同时间间隔(日期范围)内的回购数量,并在一个表格中显示这些计数。我使用了几个后续的公用表表达式(cte),我最终将它们连接在一起。然而,这种方式很麻烦且效率很低(就性能速度而言)。

我期望最短和最快的SQL代码,由于多种原因不起作用,并将返回错误消息,如 “子查询(Select(count ......)将返回多个值,因此”不能用作表达式“ 要么 另一个错误消息是:“聚合可能不会出现在WHERE子句中,除非它位于HAVING子句或选择列表中包含的子查询中,并且要聚合的列是外部引用。” 请在下面找到示例表(WDB),所需的结果表(WDB_result)和需要改进的SQL代码。非常感谢所有可能提供帮助的人!

示例WDB表:

enter image description here

  • 客户ID:客户ID
  • InNo:发票编号
  • OrderDate:订单日期

结果表WDB_result:

enter image description here

  

A)回购总数
  B)前3个月内回购的次数
  C)前6个月内的回购数量   D)前12个月内的回购数量   E)过去3个月的回购数量   F)过去6个月的回购数量
  G)过去12个月的回购数量

示例SQL代码以计算列A,B和E:

SELECT 
CustomerID
, COUNT(InNo) OVER (PARTITION by CustomerID) -1) as Norepurchases_Total
, (SELECT (COUNT(InNo) OVER (PARTITION by CustomerID) -1)  as Count3
    FROM WDB 
    WHERE OrderDate between MIN(OrderDate) and DATEADD(month, 3, MIN(OrderDate))
       ) as Norepurchases_1st_3months
 , (SELECT (COUNT(InNo) OVER (PARTITION by CustomerID) -1)  as Count3
    FROM WDB 
    WHERE OrderDate between MAX(OrderDate) and DATEPART(y, DATEADD(m, -3, getdate()))
       ) as NoRepurchases_Last_3months
FROM WDB;

2 个答案:

答案 0 :(得分:0)

通常我会在这种情况下做的事情就像

SELECT  CustormerID,
        SUM(
            CASE
                WHEN OrderDate > @ThreeMonthsAgo AND OrderDate <= @CurrentDate
                    1
                ELSE 0
            END
           ) InLast3Months,        
        SUM(
            CASE
                WHEN OrderDate > @SixMonthsAgo AND OrderDate <= @ThreeMonthsAgo 
                    1
                ELSE 0
            END
           ) InLast3To6Months,
        ...
FROM YourTable
GROUP BY CustomerID

这将使您事先确定存储桶作为变量,如图所示,然后计算存储桶中有多少项。

答案 1 :(得分:0)

这是一个非常有趣的查询,如果您阅读multiple aggregate functions上的这篇stackoverflow文章,我认为您可以实现的目标。

应用与此问题中使用的概念相同的概念可以解决您的问题。