如何对此变量进行分区,以便在过滤时其累积总量保持不变?

时间:2018-03-13 08:36:42

标签: sql sql-server tsql

我正在使用SQL Server 2012,我对表进行了以下T-SQL查询。

SELECT ID
       ,StayDate
       ,Dateadd(day, -datepart(day,StayDate) + 1, StayDate) as 'MonthOfStay'
       ,DailyRateAmount
       ,SUM(DailyRateAmount) OVER (PARTITION BY ID) AS [CummulativeRateAmt]
FROM Table1
WHERE ID = 625

以上查询的输出如下:

ID     StayDate     MonthOfStay  DailyRateAmt CummulativeRateAmt
625    2018-09-28   2018-09-01    100              400
625    2018-09-29   2018-09-01    100              400
625    2018-09-30   2018-09-01    100              400
625    2018-10-01   2018-10-01    100              400

当我在StayDate上为此查询添加过滤器时,它会为我提供以下输出:

SELECT ID
       ,StayDate
       ,Dateadd(day, -datepart(day,StayDate) + 1, StayDate) as 'MonthOfStay'
       ,DailyRateAmount
       ,SUM(DailyRateAmount) OVER (PARTITION BY ID) AS [CummulativeRateAmt]
FROM Table1
WHERE ID = 625
AND StayDate between '2018-09-28' and '2018-09-30'

输出:

ID     StayDate     MonthOfStay  DailyRateAmt CummulativeRateAmt
625    2018-09-28   2018-09-01    100              300
625    2018-09-29   2018-09-01    100              300
625    2018-09-30   2018-09-01    100              300

我正在寻找此输出,CummulativeRateAmt列值显示每个ID的所有StayDates的总费率:

ID     StayDate     MonthOfStay  DailyRateAmt CummulativeRateAmt
625    2018-09-28   2018-09-01    100              400
625    2018-09-29   2018-09-01    100              400
625    2018-09-30   2018-09-01    100              400

我知道我可以嵌套上面的第一个查询,然后在嵌套后过滤StayDates

但是,是否有分区语法允许我在不必嵌套T-SQL查询的情况下执行此操作?

2 个答案:

答案 0 :(得分:0)

您可以使用CTESub-query,然后过滤记录

WITH CTE AS (
 SELECT ID
       ,StayDate
       ,Dateadd(day, -datepart(day,StayDate) + 1, StayDate) as 'MonthOfStay'
       ,DailyRateAmount
       ,SUM(DailyRateAmount) OVER (PARTITION BY ID) AS [CummulativeRateAmt]
 FROM table t
 WHERE ID = 625
)

SELECT * FROM CTE 
WHERE StayDate between '2018-09-28' and '2018-09-30'

您也可以通过带有过滤ID的CROSS JOIN来实现这一目标,以获得总和

SELECT  ID, StayDate,
        Dateadd(day, -datepart(day,StayDate) + 1, StayDate) as 'MonthOfStay',
        DailyRateAmount,
        tt.CummulativeRateAmt
FROM table t CROSS JOIN (
      SELECT SUM(DailyRateAmount) CummulativeRateAmt FROM table WHERE ID = 625) tt
WHERE ID = 625 AND
       StayDate between '2018-09-28' and '2018-09-30'

答案 1 :(得分:0)

虽然我建议使用CTE或子查询的更明确的方法(更容易遵循预期的逻辑),但您可以使用TOP WITH TIES执行所需的操作:

SELECT TOP (1) WITH TIES ID, StayDate,
       Dateadd(day, -datepart(day,StayDate) + 1, StayDate) as MonthOfStay,
       DailyRateAmount
       SUM(DailyRateAmount) OVER (PARTITION BY ID) AS CumulativeRateAmt
FROM Table1
WHERE ID = 625
ORDER BY (CASE WHEN StayDate between '2018-09-28' and '2018-09-30' THEN 1 ELSE 2 END);