0

我试图弄清楚是否可以使用 SQL 生成人工列。

鉴于下面的假数据,您如何创建一个名为GENERATED_SEQUENCE.

规则如下:

  • 必须在同一门课程中(Id)
  • 必须在同一日期(Course_Date)
  • 每个课程会话必须在 30 分钟内(Course_Start_Time 和 Course_End_Time)

代码:

select 
    111 As Id, 'Bio 101' As Course_Name, 
    '1/10/2016' AS Course_Date, 
    '09:00:00' AS Course_Start_Time,
    '09:45:00' AS Course_End_Time, 
    1 AS GENERATED_SEQUENCE

union all

select
    111 As Id, 'Bio 101' As Course_Name, 
    '1/10/2016' AS Course_Date, 
    '10:00:00' AS Course_Start_Time,  
    '010:45:00' AS Course_End_Time, 
    2 AS GENERATED_SEQUENCE 

union all

select
    111 As Id, 'Bio 101' As Course_Name, 
    '1/10/2016' AS Course_Date, 
    '11:05:00' AS Course_Start_Time, 
    '12:30:00' AS Course_End_Time, 
    3 AS GENERATED_SEQUENCE

union all

select
    431 As Id, 'Econ 101' As Course_Name, 
    '1/12/2016' AS Course_Date, 
    '11:00:00' AS Course_Start_Time,
    '12:45:00' AS Course_End_Time, 
    1 AS GENERATED_SEQUENCE 

union all

select
    111 As Id, 'Bio 101' As Course_Name, 
    '1/12/2016' AS Course_Date, 
    '1:00:00' AS Course_Start_Time, 
    '2:45:00' AS Course_End_Time, 
    1 AS GENERATED_SEQUENCE 

union all

select
    543 As Id, 'Eng 200' As Course_Name, 
    '1/13/2016' AS Course_Date, 
    '2:00:00' AS Course_Start_Time, 
    '2:45:00' AS Course_End_Time, 
    1 AS GENERATED_SEQUENCE 

union all

select
    543 As Id, 'Eng 200' As Course_Name, 
    '1/13/2016' AS Course_Date, 
    '2:55:00' AS Course_Start_Time, 
    '3:55:00' AS Course_End_Time, 
    2 AS GENERATED_SEQUENCE 

union all

select
    543 As Id, 'Eng 200' As Course_Name, 
    '1/14/2016' AS Course_Date, 
    '6:00:00' AS Course_Start_Time, 
    '8:15:00' AS Course_End_Time, 
    1 AS GENERATED_SEQUENCE 

这可能吗?

谢谢!

4

2 回答 2

1

这是一个选项。

子查询使用:

  • Course_End_Date 上的 LAG(),因此我们可以在 DATEDIFF() 中使用它来确定上一门课程完成的分钟数。
  • 用一个案例语句评估它,以确定我们是否在 30 分钟内作为一个名为 [PrevCourseWithIn30] 的新列

然后,您可以从那里简单地使用 ROW_NUMBER() 窗口函数并按 Id、Course_Date 和我们的新 [PrevCourseWithIn30] 列进行分区,以获得新的 [GENERATED_SEQUENCE] 列

看看这个:

DECLARE @TestData TABLE
    (
        [Id] INT
      , [Course_Name] NVARCHAR(100)
      , [Course_Date] DATE
      , [Course_Start_Time] TIME
      , [Course_End_Time] TIME
    );

INSERT INTO @TestData (
                          [Id]
                        , [Course_Name]
                        , [Course_Date]
                        , [Course_Start_Time]
                        , [Course_End_Time]
                      )
            SELECT 111 AS [Id]
                 , 'Bio 101' AS [Course_Name]
                 , '2016-01-10' AS [Course_Date]
                 , '09:00:00' AS [Course_Start_Time]
                 , '09:45:00' AS [Course_End_Time]
            UNION ALL
            SELECT 111 AS [Id]
                 , 'Bio 101' AS [Course_Name]
                 , '2016-01-10' AS [Course_Date]
                 , '10:00:00' AS [Course_Start_Time]
                 , '10:45:00' AS [Course_End_Time]
            UNION ALL
            SELECT 111 AS [Id]
                 , 'Bio 101' AS [Course_Name]
                 , '2016-01-10' AS [Course_Date]
                 , '11:05:00' AS [Course_Start_Time]
                 , '12:30:00' AS [Course_End_Time]
            UNION ALL
            SELECT 431 AS [Id]
                 , 'Econ 101' AS [Course_Name]
                 , '2016-01-12' AS [Course_Date]
                 , '11:00:00' AS [Course_Start_Time]
                 , '12:45:00' AS [Course_End_Time]
            UNION ALL
            SELECT 111 AS [Id]
                 , 'Bio 101' AS [Course_Name]
                 , '2016-01-12' AS [Course_Date]
                 , '1:00:00' AS [Course_Start_Time]
                 , '2:45:00' AS [Course_End_Time]
            UNION ALL
            SELECT 543 AS [Id]
                 , 'Eng 200' AS [Course_Name]
                 , '2016-01-13' AS [Course_Date]
                 , '2:00:00' AS [Course_Start_Time]
                 , '2:45:00' AS [Course_End_Time]
            UNION ALL
            SELECT 543 AS [Id]
                 , 'Eng 200' AS [Course_Name]
                 , '2016-01-13' AS [Course_Date]
                 , '2:55:00' AS [Course_Start_Time]
                 , '3:55:00' AS [Course_End_Time]
            UNION ALL
            SELECT 543 AS [Id]
                 , 'Eng 200' AS [Course_Name]
                 , '2016-01-14' AS [Course_Date]
                 , '6:00:00' AS [Course_Start_Time]
                 , '8:15:00' AS [Course_End_Time];


SELECT *
     , ROW_NUMBER() OVER ( PARTITION BY [CS].[Id]
                                      , [CS].[Course_Date]
                                      , [CS].[PrevCourseWithIn30]
                           ORDER BY [CS].[Course_Start_Time]
                         ) AS [GENERATED_SEQUENCE]
FROM   (
           SELECT *
                , CASE WHEN DATEDIFF(
                                        MINUTE
                                      , LAG(
                                              [Course_End_Time]
                                            , 1
                                            , [Course_Start_Time]
                                          ) OVER ( PARTITION BY [Id]
                                                              , [Course_Date]
                                                   ORDER BY [Course_Start_Time]
                                                 )
                                      , [Course_Start_Time]
                                    ) <= 30 THEN 1
                       ELSE 0
                  END AS [PrevCourseWithIn30]
           FROM   @TestData
       ) AS [CS];
于 2019-01-07T21:15:51.030 回答
1

这是一个使用 CTE 存储数据以及 RANK() 和 LEAD() 函数的选项。

WITH cteCourse
AS (SELECT 111 AS Id,
           'Bio 101' AS Course_Name,
           '1/10/2016' AS Course_Date,
           '09:00:00' AS Course_Start_Time,
           '09:45:00' AS Course_End_Time
    UNION ALL
    SELECT 111 AS Id,
           'Bio 101' AS Course_Name,
           '1/10/2016' AS Course_Date,
           '10:00:00' AS Course_Start_Time,
           '10:45:00' AS Course_End_Time
    UNION ALL
    SELECT 111 AS Id,
           'Bio 101' AS Course_Name,
           '1/10/2016' AS Course_Date,
           '11:05:00' AS Course_Start_Time,
           '12:30:00' AS Course_End_Time
    UNION ALL
    SELECT 431 AS Id,
           'Econ 101' AS Course_Name,
           '1/12/2016' AS Course_Date,
           '11:00:00' AS Course_Start_Time,
           '12:45:00' AS Course_End_Time
    UNION ALL
    SELECT 111 AS Id,
           'Bio 101' AS Course_Name,
           '1/12/2016' AS Course_Date,
           '13:00:00' AS Course_Start_Time,
           '14:45:00' AS Course_End_Time
    UNION ALL
    SELECT 543 AS Id,
           'Eng 200' AS Course_Name,
           '1/13/2016' AS Course_Date,
           '14:00:00' AS Course_Start_Time,
           '14:45:00' AS Course_End_Time
    UNION ALL
    SELECT 543 AS Id,
           'Eng 200' AS Course_Name,
           '1/13/2016' AS Course_Date,
           '14:55:00' AS Course_Start_Time,
           '15:55:00' AS Course_End_Time
    UNION ALL
    SELECT 543 AS Id,
           'Eng 200' AS Course_Name,
           '1/14/2016' AS Course_Date,
           '18:00:00' AS Course_Start_Time,
           '20:15:00' AS Course_End_Time)
SELECT Id,
       Course_Name,
       Course_Date,
       Course_Start_Time,
       Course_End_Time,
       CASE
           WHEN Course_End_Time + '00:30:00' <= LEAD(Course_Start_Time, 1, 0) OVER (ORDER BY Course_Name,
                                                                                             Course_Date,
                                                                                             Course_Start_Time,
                                                                                             Course_End_Time
                                                                                   ) THEN
               RANK() OVER (PARTITION BY Id,
                                         Course_Date
                            ORDER BY Course_Start_Time,
                                     Course_End_Time
                           )
           ELSE
               1
       END AS GENERATED_SEQUENCE
FROM cteCourse;

在下面回答您的问题,您可以将第二个查询转换为 CTE 并像表格一样从中查询。例如:

,cteGenSeq AS (
SELECT Id,
       Course_Name,
       Course_Date,
       Course_Start_Time,
       Course_End_Time,
       CASE
           WHEN Course_End_Time + '00:30:00' <= LEAD(Course_Start_Time, 1, 0) OVER (ORDER BY Course_Name,
                                                                                             Course_Date,
                                                                                             Course_Start_Time,
                                                                                             Course_End_Time
                                                                                   ) THEN
               RANK() OVER (PARTITION BY Id,
                                         Course_Date
                            ORDER BY Course_Start_Time,
                                     Course_End_Time
                           )
           ELSE
               1
       END AS GENERATED_SEQUENCE
FROM cteCourse
)

SELECT * FROM cteGenSeq
于 2019-01-07T21:23:21.917 回答