创建SQL视图以递归方式搜索计划表

时间:2016-06-08 19:30:34

标签: sql sql-server

我试图想出一种在MS SQL Server中创建视图的方法,以自动检查同一个表中的计划冲突。我想看看是否可以创建一个视图来添加列并列出冲突的reservation_id

我的表格如下:

reservation_id - integer
reservation_start - datetime
reservation_end - datetime

以下是一些示例数据:

1, 2016-07-21 06:30:00.000, 2016-07-21 07:30:00.000
2, 2016-07-21 07:00:00.000, 2016-07-22 09:00:00.000
3, 2016-08-02 08:45:00.000, 2016-08-03 09:45:00.000
4, 2016-08-02 03:00:00.000, 2016-08-02 09:00:00.000
5, 2016-08-27 02:30:00.000, 2016-08-28 03:30:00.000
6, 2016-08-30 09:00:00.000, 2016-08-30 09:00:00.000

所以,我想创建一个看起来像这样的视图:

reservation_id, reservation_start, reservation_end, conflicts
1, 2016-07-21 06:30:00.000, 2016-07-21 07:30:00.000, [2]
2, 2016-07-21 07:00:00.000, 2016-07-22 09:00:00.000, [1]
3, 2016-08-02 08:45:00.000, 2016-08-03 09:45:00.000, [4]
4, 2016-08-02 03:00:00.000, 2016-08-02 09:00:00.000, [3]
5, 2016-08-27 02:30:00.000, 2016-08-28 03:30:00.000
6, 2016-08-30 09:00:00.000, 2016-08-30 09:00:00.000

这是否可能,或者我是否需要创建一个临时表来保存这些信息?

2 个答案:

答案 0 :(得分:3)

您需要使用Cross ApplyStuff

Select 
    reservation_id,
    reservation_start,
    reservation_end,
   '[' + cf.conflicts + ']' as conflicts
FROM yourTableName t1
Cross Apply
(
    SELECT 
       STUFF
       ((
          SELECT ',' + CONVERT(VARCHAR(5), reservation_id)
          FROM yourTableName t2
          WHERE t1.reservation_id <> t2.reservation_id
           AND ((t1.reservation_start BETWEEN t2.reservation_start AND t2.reservation_end) 
             OR (t1.reservation_end BETWEEN t2.reservation_start AND t2.reservation_end))
    FOR XML PATH('')), 1, 1, '') as conflicts 
) cf
-- Where Clause Here like 'WHERE t1.reservation_id <> 1'

如果你想用这个查询创建视图,那么它就是:

CREATE VIEW YourViewName
AS
-- Select Query Here

<强>更新

;WITH CTE_Reservation
AS
(
   Select 
    reservation_id,
    reservation_start,
    reservation_end
  FROM yourTableName
  -- Where Clause Here
)

Select 
    reservation_id,
    reservation_start,
    reservation_end,
   '[' + cf.conflicts + ']' as conflicts
FROM CTE_Reservation t1
Cross Apply
(
    SELECT 
       STUFF
       ((
          SELECT ',' + CONVERT(VARCHAR(5), reservation_id)
          FROM CTE_Reservation t2
          WHERE t1.reservation_id <> t2.reservation_id
           AND ((t1.reservation_start BETWEEN t2.reservation_start AND t2.reservation_end) 
             OR (t1.reservation_end BETWEEN t2.reservation_start AND t2.reservation_end))
    FOR XML PATH('')), 1, 1, '') as conflicts 
) cf

答案 1 :(得分:0)

评论片段 - 平凡联接,它将返回所需结果但不汇总(每个冲突在单独的行上):

set(gca, 'SortMethod', 'depth')

最终片段将以逗号分隔收集冲突