【问题标题】:Dense_Rank orderingDense_Rank 排序
【发布时间】:2016-09-08 04:23:12
【问题描述】:

我已阅读此问题的一些变体,但解决方案似乎不起作用。

我希望为每个“OrderNo”和“GroupID”动态创建一个“子组”。子组应按“OrderLine”排序,例如:(预期结果)

OrderNo OrderLine   GroupID Subgroup
------------------------------------
10463   1            798    1
10463   2            799    2
10463   3            797    3
10463   5            65     4
10463   6            65     4
10463   7            65     4
10481   4            917    1
10481   5            918    2
10481   6            131    3
10481   7            131    3
10481   8            131    3
10481   9            130    4

我使用 Dense_Rank() 在下面创建了正确的组,但排序(和排名)完全不正确。

SELECT 
    OrderNo, OrderLine, GroupID,
    DENSE_RANK() OVER (PARTITION BY OrderNo ORDER BY GroupID) AS Subgroup
FROM 
    #temptable
ORDER BY
    OrderNo, OrderLine;

输出:

OrderNo OrderLine   GroupID Subgroup
------------------------------------
10463   1            798    3
10463   2            799    4
10463   3            797    2
10463   5            65     1
10463   6            65     1
10463   7            65     1
10481   4            917    3
10481   5            918    4
10481   6            131    2
10481   7            131    2
10481   8            131    2
10481   9            130    1

查询:

-- Temp tables
CREATE TABLE #temptable
(  
    OrderNo varchar(5),  
    OrderLine int, 
    GroupID int
); 

INSERT INTO #temptable (OrderNo, OrderLine, GroupID)
VALUES ('10463', '1', '798'), ('10463', '2', '799'),
       ('10463', '3', '797'), ('10463', '5', '65'),
       ('10463', '6', '65'), ('10463', '7', '65'),
       ('10481', '4', '917'), ('10481', '5', '918'),
       ('10481', '6', '131'), ('10481', '7', '131'),
       ('10481', '8', '131'), ('10481', '9', '130');

【问题讨论】:

    标签: sql sql-server-2012 sql-order-by gaps-and-islands


    【解决方案1】:

    您希望通过OrderLineDENSE_RANK 分区进行排序,但在多个记录具有相同GroupID 的情况下,您希望排名相同。一种选择是使用子查询来识别为具有相同GroupID 的一组记录的OrderLine 分配单个值(例如最小值)。然后可以将此表连接回您的#temptable,并且可以根据需要将有效的OrderLine 用于DENSE_RANK

    SELECT t1.OrderNo,
           t1.OrderLine,
           t1.GroupID,
           DENSE_RANK() OVER (PARTITION BY t1.OrderNo ORDER BY t2.OrderLine) AS Subgroup
    FROM #temptable t1
    INNER JOIN
    (
        SELECT OrderNo,
               MIN(OrderLine) AS OrderLine,
               GroupID
        FROM #temptable
        GROUP BY OrderNo,
                 GroupID
    ) t2
        ON t1.OrderNo = t2.OrderNo AND
           t1.GroupID = t2.GroupID
    

    【讨论】:

    • 不幸的是,GroupID 并不总是按顺序排列。 子组应按“OrderLine”排序,但这当然会扭曲结果
    • 使用MIN(OrderLine) 的非常聪明的解决方案,我的连接(使用多个值)正在成倍地增长数据集,我没有追求这个途径。谢谢!
    猜你喜欢
    • 2017-02-20
    • 2020-11-12
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2020-02-17
    • 2017-06-16
    相关资源
    最近更新 更多