如何根据列中的值动态生成行

njk*_*oes 2 data-warehouse sql-server t-sql

我正在尝试编写一个查询来对一些数据进行非规范化以集成到我们的数据仓库中,特别是围绕生成一些时隙。

在我的源系统中,我有一个表,它有一个开始时间和结束时间,然后有一列指定每 15 分钟间隔有多少约会空档可用。

例子:

    Location | Start Time | End Time | Appointment Slots
    A        | 9:00 am    | 5:00 pm  | 2
    B        | 9:00 am    | 5:00 pm  | 1
Run Code Online (Sandbox Code Playgroud)

我已经能够使用 CTE 生成 15 分钟块的列表。但是,每个 15 分钟的插槽只是说位置 A 有 2 个插槽可用,位置 B 有 1 个插槽可用。我想要的是能够为位置 A 每 15 分钟生成 2 行,每 15 分钟生成 1 行对于位置 B。

小智 5

这是一个“数字”表变得非常方便的例子!如果您不熟悉这个概念,请阅读 Adam Machanic 的这篇博文:您需要一个数字表

numbers 表用于连接到 Appointment Slots 列(在本例中)以复制每行AppointmentSlots次数。

-- A simple recreation of your CTE data...
CREATE  TABLE #AppointmentPeriods
(
    AppointmentLocation CHAR(1),
    AppointmentStartTime TIME,
    AppointmentEndTime TIME,
    AppointmentSlotsAvailable SMALLINT
)

INSERT  INTO #AppointmentPeriods VALUES
    ('A', '09:00', '09:15', 2),
    ('A', '09:15', '09:30', 2),
    ('A', '09:30', '09:45', 2),
    -- ....
    ('A', '16:30', '16:45', 2),
    ('A', '16:45', '17:00', 2),
    ('B', '09:00', '09:15', 1),
    ('B', '09:15', '09:30', 1),
    ('B', '09:30', '09:45', 1),
    -- ....
    ('B', '16:30', '16:45', 1),
    ('B', '16:45', '17:00', 1)


-- Numbers table
CREATE  TABLE #Numbers (NumberValue SMALLINT)

INSERT  INTO #Numbers
-- TOP value should be changed so it is greater than the
-- maximum number of potential appointment slots any location can have
SELECT  TOP 20
        ROW_NUMBER() OVER (ORDER BY object_id)
FROM    sys.objects


SELECT  #AppointmentPeriods.*, NumberValue AS AppointmentSlotNumber
FROM    #AppointmentPeriods
        INNER JOIN #Numbers
            ON AppointmentSlotsAvailable >= NumberValue
Run Code Online (Sandbox Code Playgroud)

查询输出:

Location | StartTime | EndTime | AppointmentSlots | SlotNumber
A        | 09:00     | 09:15   | 2                | 1
A        | 09:00     | 09:15   | 2                | 2
A        | 09:15     | 09:30   | 2                | 1
A        | 09:15     | 09:30   | 2                | 2
B        | 16:30     | 16:45   | 1                | 1
B        | 16:45     | 17:00   | 1                | 1
Run Code Online (Sandbox Code Playgroud)

PS:生成数字表的方法有很多:SO:创建和填充数字表的最佳方法是什么?