在 SQL 服务器中使用 Top 将字段拆分为段

Using Top to split a field into segments in SQL Server

我有两张桌子。

Table一个

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

Table 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 个顺序,依此类推。 日期 Table A = 日期 Table B.

Table 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     ║
╚═════════════════════════════════════════╝

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

-- 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 使用率低。