分为2周

时间:2016-08-17 04:26:54

标签: sql sql-server-2008

我有一个表(称为' transactions'),其中包含客户交易数据。每行包含客户编号和交易日期。我需要显示每个客户在规定的2周内完成的交易总数。对于所有客户,2周时间从2016年8月22日开始。因此,我需要知道每个客户在从2002年8月22日起的2周内滚动的交易数量。

我需要返回以显示客户编号,每两周期间的开始日期以及该两周期间的交易次数。

例如,下面的示例数据:

╔══════════╦════════════╗
║ Customer ║ Date       ║
╠══════════╬════════════╣
║ 1234     ║ 22/08/2016 ║
╠══════════╬════════════╣
║ 1234     ║ 23/08/2016 ║
╠══════════╬════════════╣
║ 1234     ║ 24/08/2016 ║
╠══════════╬════════════╣
║ 1234     ║ 3/09/2016  ║
╠══════════╬════════════╣
║ 1234     ║ 3/09/2016  ║
╠══════════╬════════════╣
║ 5678     ║ 26/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 27/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 28/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 29/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 30/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 30/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 30/08/2016 ║
╠══════════╬════════════╣
║ 5678     ║ 6/09/2016  ║
╠══════════╬════════════╣
║ 5678     ║ 6/09/2016  ║
╠══════════╬════════════╣
║ 5678     ║ 7/09/2016  ║
╠══════════╬════════════╣
║ 5678     ║ 8/09/2016  ║
╠══════════╬════════════╣
║ 5678     ║ 12/09/2016 ║
╚══════════╩════════════╝

需要退货:


╔══════════╦═════════════════╦═══════╗
║ Customer ║ Week Start Date ║ Count ║
╠══════════╬═════════════════╬═══════╣
║ 1234     ║ 22/08/2016      ║ 5     ║
╠══════════╬═════════════════╬═══════╣
║ 5678     ║ 22/08/2016      ║ 7     ║
╠══════════╬═════════════════╬═══════╣
║ 5678     ║ 5/09/2016       ║ 5     ║
╚══════════╩═════════════════╩═══════╝

1 个答案:

答案 0 :(得分:1)

仔细检查后,您的预期结果对我来说有点意外,因为您列出了客户ID以及客户数量的总和。通常情况下,您只需要预计每两周一次的客户总数,这是我下面的查询应该生成的。

SELECT t.Customer,
       DATEADD(day, (t.twoWeekPeriod-1)*14 + 3, '2016-01-01') AS [Week Start Date],
       t.customerCount AS [Count]
FROM
(
    SELECT Customer,
           FLOOR(DATEPART(week, DATEADD(day, -3, Date)) / 2) AS twoWeekPeriod,
           COUNT(*) AS customerCount
    FROM yourTable
    WHERE Date >= '2016-08-22'
    GROUP BY Customer,
             FLOOR(DATEPART(week, DATEADD(day, -3, Date)) / 2)
) t

<强>解释

  • SQL Server开始第一周&#34;周&#34; 1月1日的一年。由于您的开始日期为22-Aug-2016,因此第一周(以及随后的所有周)将于周五开始。由于您的开始日期是星期一,因此我将所有日期回滚3天以使所有内容保持一致。
  • 22-Aug-2016回滚了3天,现在是今年第34周的开始。这意味着第35周也应该是前两周的一部分。
  • FLOOR(DATEPART(week, DATEADD(day, -3, Date)) / 2)在一个为期两周的时间内将14天组合在一起

<强>更新

正如您所指出的,如果您的数据跨越多个日历年,则上述查询无法按预期工作。在这种情况下,您可以使用单独的天数形成两周的小组,其中2016-08-22(或您想要的任何其他日期)作为前两周的时间段:

SELECT t.Customer,
       DATEADD(day, (t.twoWeekPeriod)*14, '2016-08-22') AS [Week Start Date],
       t.customerCount AS [Count]
FROM
(
    SELECT Customer,
           FLOOR(DATEDIFF(day, '2016-08-22', Date) / 14) AS twoWeekPeriod,
           COUNT(*) AS customerCount
    FROM yourTable
    WHERE Date >= '2016-08-22'
    GROUP BY Customer,
             FLOOR(DATEDIFF(day, '2016-08-22', Date) / 14)
) t