0

假设我有一张这样的桌子:

CREATE TABLE [dbo].[Scheduler](
    [DayOfWeek] [tinyint] NOT NULL,
    [Time] [time](0) NOT NULL,
    [Action] [varchar](255) NOT NULL
)

还有一些数据,像这样:

INSERT INTO Scheduler VALUES (1, '11:00:00', 'Sunday')
INSERT INTO Scheduler VALUES (2, '12:00:00', 'Monday')
INSERT INTO Scheduler VALUES (4, '13:00:00', 'Tuesday')
INSERT INTO Scheduler VALUES (8, '14:00:00', 'Wednesday')
INSERT INTO Scheduler VALUES (16, '15:00:00', 'Thursday')
INSERT INTO Scheduler VALUES (32, '16:00:00', 'Friday')
INSERT INTO Scheduler VALUES (64, '17:00:00', 'Saturday')
INSERT INTO Scheduler VALUES (62, '06:00:00', 'Every business day')
INSERT INTO Scheduler VALUES (127, '08:00:00', 'Every day')

如果 DayOfWeek 有多个标志,如何在 SELECT 语句中生成多行?

例如,这一行:

INSERT INTO Scheduler VALUES (62, '06:00:00', 'Every business day')

它将在 SELECT 语句中以 5 行表示(每一天/标志集一个)

DayOfWeek Time             Message
--------- ---------------- ---------------------------
2         06:00:00         Every business day
4         06:00:00         Every business day
8         06:00:00         Every business day
16        06:00:00         Every business day
32        06:00:00         Every business day

对所有数据运行相同的查询会给我 19 行。

  • 7 行 - 每一天 (1, 2, 4, 8, 16, 32, 64)
  • 5 行 - 工作日 (62)
  • 7 行 - 每天 (127)

我不确定我该怎么做。我想我可以使用光标来做到这一点,但这是最好的选择吗?

谢谢。

4

1 回答 1

0

您需要 SQL Server 的位运算符。此示例说明如何确定当前值中包含哪些标志。

DECLARE @Mon        INT = 1;
DECLARE @Tue        INT = 2;
DECLARE @Wed        INT = 4;
DECLARE @MonAndTue  INT = 3;    -- Mon (1) and Tue (2) = 3.

SELECT
    @MonAndTue & @Mon,      -- Contains Monday, returns Monday.
    @MonAndTue & @Tue,      -- Contains Tuesday, returns Tuesday.
    @MonAndTue & @Wed       -- Does not contain Wednesday, returns 0.

在可能的情况下,我建议避免在 SQL Server 中使用基于位掩码的解决方案。这些在其他语言中效果很好(想到 C 语言)。但是当每列包含一个值,描述单个项目时,SQL 效果最好。当然,您可以将这些方法结合起来。此表设计允许您保留基本 2 个键(非常适合前端)并包含简单的位字段,使后端中的过滤成为一项简单的任务。

CREATE TABLE [Day]
(
    DayId       INT PRIMARY KEY,        
    [DayName]   VARCHAR(9),
    IsMonday    BIT,
    IsTuesday   BIT,
    ...
    IsSunday    BIT
)
;

编辑

对不起!我实际上并没有回答你的问题。要在连接中使用按位运算,您需要使用以下几行语法:

WITH Scheduler AS
(
    /* Sample data.
     */
    SELECT          
        *
    FROM
        (
            VALUES  
                (1, 'Sunday'),
                (2, 'Monday'),
                (4, 'Tuesday'),
                (8, 'Wednesday'),
                (16, 'Thursday'),
                (32, 'Friday'),
                (64, 'Saturday'),
                (62, 'Every business day'),
                (127, 'Every day')
        ) AS r(DayId, [DayName])
)
/* This join returns every day from s2 that 
 * is contained within the s1 record Every business day.
 */
SELECT
    *
FROM
    Scheduler AS s1
        INNER JOIN Scheduler AS s2          ON (s1.DayId & s2.DayId) =     s2.DayId
WHERE
    s1.DayId = 62
;

这里 S1 被过滤以返回Every business day。S2 在找到匹配项的 S1 上加入。这将返回周一、周二、周三等,而不返回周六和周日。

于 2016-02-03T10:17:18.397 回答