将生成的列添加到SQL查询结果的末尾

时间:2019-01-07 20:17:51

标签: sql-server tsql sql-server-2012

我正在尝试确定是否可以使用SQL生成人工列。

鉴于下面的虚假数据,如何创建一个名为GENERATED_SEQUENCE的生成的列。

规则如下:

  • 必须在同一课程中(Id)
  • 必须在同一日期(课程日期)
  • 每个课程会话之间的时间间隔必须在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 

这可能吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

这是一个选择。

子查询使用:

  • LAC()在Course_End_Date上,因此我们可以在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];

答案 1 :(得分: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