SQL Server 是否返回一行基于日期的各种总和?

vkc1a9a2  于 2023-01-29  发布在  其他
关注(0)|答案(3)|浏览(120)

假设一个包含CustId, Amount, DatePosted列的采购事务处理表,其中Amount是事务处理的值,DatePosted是DATETIME值。给定一个特定的CustId,如何编写select语句,使其返回包含以下列的单行:CustId,过去3天、过去60天、1年、2年的交易总值(共5列)。
示例表:
| 客户ID|金额|发布日期|
| - ------|- ------|- ------|
| 1234|六百九十八点零二分|2023年1月23日12时34分56秒|
| 1234|五百八十二点六九|2022年12月15日19时57分23秒|
| 1234|小行星7775.22|2022年12月2日零时2分34秒32|
| 1234|十八点七二分|2022年1月23日12时34分56秒|
| 1234|二点二七分|2021年1月23日12时34分56秒|
使用CustId=1234进行搜索时,上述示例数据的预期输出为:
| 客户ID|3天总计|60天总计|1年共计|2年共计|
| - ------|- ------|- ------|- ------|- ------|
| 1234|六百九十八点零二分|小行星9055.93|九千零七十四点六五|小行星9076.92|

zfycwa2u

zfycwa2u1#

您可以获取过去2年的所有购买数据,然后使用SUM和SQL CASE expression计算每个时间范围的总值。

SELECT 
  CustId, 
  SUM(CASE WHEN DatePosted >= Last3Day THEN Amount ELSE 0 END) AS [3-day Total],
  SUM(CASE WHEN DatePosted >= Last60Day THEN Amount ELSE 0 END) AS [60-day Total],
  SUM(CASE WHEN DatePosted >= Last1Year THEN Amount ELSE 0 END) AS [1 year Total],
  SUM(CASE WHEN DatePosted >= Last2Year THEN Amount ELSE 0 END) AS [2 year Total]
FROM 
  <your data table>,
  (SELECT 
      DATEADD(DAY, -3, GETDATE()) AS Last3Day,
      DATEADD(DAY, -60, GETDATE()) AS Last60Day,
      DATEADD(YEAR, -1, GETDATE()) AS Last1Year,
      DATEADD(YEAR, -2, GETDATE()) AS Last2Year) timerange
WHERE DatePosted >= Last2Year      
GROUP BY CustId;

演示版:http://sqlfiddle.com/#!18/9 eecb/179880

r7xajy2e

r7xajy2e2#

此查询假定最长为2年。如果您想继续返回,则还需更改where子句。无需使用合并或派生表。SQL Server查询规划器可能足够智能,可以为所有这些解决方案提供类似的性能,但这更易于理解:

SELECT 
    CustId, 
    SUM(CASE WHEN DatePosted >= DATEADD(day, -3, GETDATE()) THEN Amount ELSE 0 END) AS [3-day Total], 
    SUM(CASE WHEN DatePosted >= DATEADD(day, -60, GETDATE()) THEN Amount ELSE 0 END) AS [60-day Total], 
    SUM(CASE WHEN DatePosted >= DATEADD(year, -1, GETDATE()) THEN Amount ELSE 0 END) AS [1 year Total], 
    SUM(Amount) AS [2 year Total]
FROM PurchaseTransactions
WHERE CustId = 1234 AND DatePosted >= DATEADD(year, -2, GETDATE())
GROUP BY CustId
fiei3ece

fiei3ece3#

这样设置后,您可以设置@CustID = null,查询将返回集合中所有客户的结果。
编辑:更新了我下面的查询,让你在你想要的范围内获得更多的灵活性,如果你想得到额外的启发式。(计数,平均值,等)也删除了合并,因为它根本不需要在这里。

DECLARE @CustID BIGINT;

SELECT table1.custID,
    SUM([3Day].amount) AS [3DayTotal],
    COUNT([3Day].amount) AS [3DayCount]
    SUM([60Day].amount) AS [60DayTotal],
    SUM([1Year].amount) AS [1YearTotal],
    Sum([2Year].amount) AS [2YearTotal],
    AVG([2Year].amount) AS [2YearAverage]
FROM table1 LEFT OUTER JOIN
    (SELECT custID, Amount FROM table1 WHERE DatePosted > DATEADD(DAY, -3, GETDATE())) AS [3Day] ON table1.CustID = [3Day].CustID LEFT OUTER JOIN
    (SELECT custID, Amount FROM table1 WHERE DatePosted > DATEADD(DAY, -60, GETDATE())) AS [60Day] ON table1.CustID = [60Day].CustID LEFT OUTER JOIN
    (SELECT custID, Amount FROM table1 WHERE DatePosted > DATEADD(YEAR, -1, GETDATE())) AS [1Year] ON table1.CustID = [1Year].CustID LEFT OUTER JOIN
    (SELECT custID, Amount FROM table1 WHERE DatePosted > DATEADD(YEAR, -2, GETDATE()) AS [2Year] ON table1.CustID = [2Year].CustID
WHERE table1.CustID = @CustID 
    OR @CustID IS NULL
GROUP BY table1.CustID

相关问题