使用Top将字段拆分为SQL Server中的段

时间:2015-07-06 19:15:25

标签: sql-server tile rank

我有两张桌子。

表A

╔══════════════════════════════════════════╗
║ Date            Segment        Total     ║
╠══════════════════════════════════════════╣
║ 11/04/2015        1            3         ║
║ 12/04/2015        3            2         ║
║ 13/04/2015        5            1         ║
╚══════════════════════════════════════════╝

表B

╔══════════════════════════════════════════╗
║ Date            Sequence         Segment ║
╠══════════════════════════════════════════╣
║ 11/04/2015        4               null   ║
║ 11/04/2015        2               null   ║
║ 11/04/2015        9               null   ║
║ 11/04/2015        6               null   ║
║ 11/04/2015        12              null   ║
║ 12/04/2015        9               null   ║
║ 12/04/2015        5               null   ║
║ 12/04/2015        1               null   ║
║ 13/04/2015        4               null   ║
║ 13/04/2015        6               null   ║
║ 13/04/2015        2               null   ║
╚══════════════════════════════════════════╝

最终输出应如下所示。段1具有前3个序列,依此类推。 表A上的日期=表B上的日期。

表B

╔═════════════════════════════════════════╗
║ Date            Sequence        Segment ║
╠═════════════════════════════════════════╣
║ 11/04/2015        4               1     ║
║ 11/04/2015        2               1     ║
║ 11/04/2015        9               null  ║
║ 11/04/2015        6               1     ║
║ 11/04/2015        12              null  ║
║ 12/04/2015        9               null  ║
║ 12/04/2015        5               3     ║
║ 12/04/2015        1               3     ║
║ 13/04/2015        4               null  ║
║ 13/04/2015        6               null  ║
║ 13/04/2015        2               5     ║
╚═════════════════════════════════════════╝

1 个答案:

答案 0 :(得分:2)

根据您在问题中描述的给定输入。您可以将其用作解决方案:

-- Create demo data
CREATE TABLE #a(date date, segment int, total int)

INSERT INTO #a(date, segment, total)
VALUES  (N'04/11/2015',1,3),
        (N'04/12/2015',3,2),
        (N'04/13/2015',5,1)

CREATE TABLE #b(date date, sequence int, segment int)

INSERT INTO #b(date, sequence)
VALUES  (N'04/11/2015',4),
        (N'04/11/2015',2),
        (N'04/11/2015',9),
        (N'04/11/2015',6),
        (N'04/11/2015',12),
        (N'04/12/2015',9),
        (N'04/12/2015',5),
        (N'04/12/2015',1),
        (N'04/13/2015',4), 
        (N'04/13/2015',6), 
        (N'04/13/2015',2)

-- Your part
SELECT b.date, b.sequence, a.segment
FROM #a as a
RIGHT JOIN (
        SELECT date, sequence, segment,
            ROW_NUMBER() OVER(PARTITION BY date ORDER BY sequence) as seqRank
        FROM #b
    ) as b
    ON b.date = a.date
    AND b.seqRank <= a.total

-- Cleanup
DROP TABLE #a
DROP TABLE #b

它将提供此输出:

date       sequence    segment
---------- ----------- -----------
2015-04-11 2           1
2015-04-11 4           1
2015-04-11 6           1
2015-04-11 9           NULL
2015-04-11 12          NULL
2015-04-12 1           3
2015-04-12 5           3
2015-04-12 9           NULL
2015-04-13 2           5
2015-04-13 4           NULL
2015-04-13 6           NULL

由于我正在使用ROW_NUMBER,它甚至可以在具有相同日期和序列号的重复项上使用。其他优点是低CPU使用率。