在T-SQL中使用Window函数进行类别列计算

时间:2019-06-10 07:47:39

标签: sql sql-server tsql window-functions

我的问题很简单,但我找不到解决方案-可能是使用窗口函数,我有以下示例数据:

ID  OrderDate   TotalOrder
--------------------------
1   2019-01-01   5
2   2019-01-02   3
3   2019-01-03   1
4   2019-01-04  15
5   2019-01-05  20
6   2019-01-06  18
7   2019-01-07   2
8   2019-01-08   4
9   2019-01-09   9

所需的结果是:

ID  OrderDate   TotalOrder  Category
-------------------------------------
1   2019-01-01   5          1
2   2019-01-02   3          1
3   2019-01-03   1          1
4   2019-01-04  15          2
5   2019-01-05  20          2
6   2019-01-06  18          2
7   2019-01-07   2          3
8   2019-01-08   4          3
9   2019-01-09   9          3

Category列是根据TotalOrder值的范围计算的。

如果TotalOrder的值小于10,则Category的值将增加。

2 个答案:

答案 0 :(得分:3)

您可以使用LAGSUM OVER()

-- Create sample data
CREATE TABLE #Tbl(
    ID          INT,
    OrderDate   DATE,
    TotalOrder  INT
);
INSERT INTO #Tbl VALUES
(1, '2019-01-01', 5),   (2, '2019-01-02', 3),   (3, '2019-01-03', 1),
(4, '2019-01-04', 15),  (5, '2019-01-05', 20),  (6, '2019-01-06', 18),
(7, '2019-01-07', 2),   (8, '2019-01-08', 4),   (9, '2019-01-09', 9);

-- Query
WITH Cte AS(
    SELECT *,
        LessThanTen = CASE WHEN TotalOrder < 10 THEN 1 ELSE 0 END
    FROM #Tbl
),
CteLag AS (
    SELECT *,
        Prev = LAG(LessThanTen, 1, NULL) OVER(ORDER BY OrderDate, ID)
    FROM Cte
)
SELECT
    ID,
    OrderDate,
    TotalOrder,
    Category = SUM(CASE WHEN Prev = LessThanTen THEN 0 ELSE 1 END) OVER(ORDER BY OrderDate, ID)
FROM CteLag
ORDER BY OrderDate, ID;

-- Cleanup
DROP TABLE #Tbl;

ONLINE DEMO

答案 1 :(得分:1)

基于示例数据和预期结果,
我认为您的意思是,当当前行的category列与上一行的TotalOrder列之间的差值大于或等于10时,您想在TotalOrder列中添加一个这些行由OrderDate列确定。

因此,借助于Felix的答案的示例数据,我认为您正在寻找类似的东西:

WITH CTE AS
(
SELECT  Id, 
        OrderDate, 
        TotalOrder,
        -- IIF is shorthand for case then else
        IIF(
            -- if the difference in TotalOrder between current row and previous row is more than 10.
            ABS(TotalOrder - ISNULL(LAG(TotalOrder) OVER(ORDER BY OrderDate), TotalOrder - 11)) > 10
            , 1
            , 0
        ) As IsDiffMoreThanTen

FROM #Tbl
)

SELECT  Id, 
        OrderDate, 
        TotalOrder,
        -- sum the IsDiffMoreThanTen column over order by OrderDate.
        SUM(IsDiffMoreThanTen) OVER(ORDER BY OrderDate) AS Category
FROM CTE

结果:

Id  OrderDate   TotalOrder  Category
1   01.01.2019  5           1
2   02.01.2019  3           1
3   03.01.2019  1           1
4   04.01.2019  15          2
5   05.01.2019  20          2
6   06.01.2019  18          2
7   07.01.2019  2           3
8   08.01.2019  4           3
9   09.01.2019  9           3