Dense_Rank订购

时间:2016-09-08 04:23:13

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

我已经阅读了这个问题的一些变体,但解决方案似乎并没有奏效。

我希望动态创建一个"子组"对于每个" OrderNo" &安培; "的GroupID&#34 ;.子组应按" 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');

1 个答案:

答案 0 :(得分:1)

您希望按DENSE_RANK订购OrderLine分区,但如果多个记录具有相同的GroupID,则您希望排名相同。一种选择是使用子查询来标识为具有相同OrderLine的一组记录分配GroupID的单个值(比如最小值)。然后,可以将此表连接回#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