使用mssql选择一系列记录

时间:2016-08-04 05:50:32

标签: sql sql-server

我在TimeLines中有一个包含记录的表,我需要获得形成45分钟链的行。

1|2016-01-01 00:00
2|2016-01-01 00:30
3|2016-01-01 00:45
4|2016-01-01 01:00

如何从时间上找到第2行,导致第2行,第3行和第4行是不可分割的15分钟链时间线45分钟设置? 第1和第2不合适,导致时间线之间的间隔为30分钟。

第2行,第3行和第4行是一致的时间轴链。 第二排加上15分钟 - 没关系。导致与该时间存在的第3行。 第3排加15分钟 - 没关系。因为那个时候存在第4行。 结果我有45分钟一致的时间表链。

1row加15分钟 - 不行。导致00:15时间与日期不存在。

3 个答案:

答案 0 :(得分:0)

试试这个

    DECLARE @Tbl TABLE (Id INT, StartDate DATETIME)
INSERT INTO @Tbl
VALUES 
(1,'2016-01-01 00:00'),
(2,'2016-01-01 00:30'),
(3,'2016-01-01 00:45'),
(4,'2016-01-01 01:00')


;WITH CTE
AS
(
    SELECT
        Id ,
        StartDate,
        ROW_NUMBER() OVER (ORDER BY Id) AS RowId
    FROM
    @Tbl
)


SELECT
    CurRow.*,   
    CASE 
        WHEN 
            DATEDIFF(MINUTE, CurRow.StartDate, NextRow.StartDate ) = 15  OR
            DATEDIFF(MINUTE, PrevRow.StartDate, CurRow.StartDate ) = 15  
            THEN '15 MIN'
        ELSE 'NO' END Flag
FROM
    CTE CurRow LEFT JOIN 
    (SELECT *, C.RowId - 1 AS TmpRowId  FROM CTE C) NextRow ON CurRow.RowId = NextRow.TmpRowId LEFT JOIN 
    (SELECT *, C.RowId + 1 AS TmpRowId  FROM CTE C) PrevRow ON CurRow.RowId = PrevRow.TmpRowId

输出:

Id  StartDate                   RowId   Flag
1   2016-01-01 00:00:00.000     1       NO
2   2016-01-01 00:30:00.000     2       15 MIN
3   2016-01-01 00:45:00.000     3       15 MIN
4   2016-01-01 01:00:00.000     4       15 MIN

答案 1 :(得分:0)

如果我理解正确,您可以使用LEAD / LAG:

WITH Src AS
(
    SELECT * FROM (VALUES 
    (1,'2016-01-01 00:00'),
    (2,'2016-01-01 00:30'),
    (3,'2016-01-01 00:45'),
    (4,'2016-01-01 01:00')) T(ID, [Date])
)
SELECT *, CASE WHEN LEAD([Date]) OVER (ORDER BY ID)=DATEADD(MINUTE, 15, [Date])
                 OR LAG([Date]) OVER (ORDER BY ID)=DATEADD(MINUTE, -15, [Date])
              THEN 'Chained' END [Status]
FROM Src

它产生:

ID  Date                Status
--  ----                ------
1   2016-01-01 00:00    NULL
2   2016-01-01 00:30    Chained
3   2016-01-01 00:45    Chained
4   2016-01-01 01:00    Chained

答案 2 :(得分:0)

您可以使用OUTER APPLY和棘手的ROW_NUMBER():

执行此操作
<section>
<body>

<table style="width:90%"  align="center">
  <tr>
    <th>Date</th>
    <th>Type</th>
    <th>Level</th>
  </tr>
  <tr ng-repeat="d in diaries">
    <td>{{d.date}}</td>
    <td>{{d.taken}}</td>
    <td style={{buttonClass}}>{{d.level}}</td>
  </tr>
</table>
</body>
</section>

输出:

;WITH TimeLines AS (  --This CTE is similar to your table
SELECT *
FROM (VALUES
(1, '2016-01-01 00:00'),(2, '2016-01-01 00:30'),
(3, '2016-01-01 00:45'),(4, '2016-01-01 01:00'),
(5, '2016-01-01 01:05'),(6, '2016-01-01 01:07'),
(7, '2016-01-01 01:15'),(8, '2016-01-01 01:30'),
(9, '2016-01-01 01:45'),(10, '2016-01-01 02:00')
) as t(id, datum)
)
, cte AS (
SELECT  t.id,
        t.datum,
        CASE WHEN ISNULL(DATEDIFF(MINUTE,t1.datum,t.datum),0) != 15 THEN DATEDIFF(MINUTE,t.datum,t2.datum) ELSE 15 END as i
FROM TimeLines t  --in this cte with the help of
OUTER APPLY (     --OUTER APPLY we are getting next and previous dates to compare them
    SELECT TOP 1 * 
    FROM TimeLines 
    WHERE t.datum > datum 
    ORDER BY datum desc) t1
OUTER APPLY (
    SELECT TOP 1 * 
    FROM TimeLines 
    WHERE t.datum < datum 
    ORDER BY datum asc) t2
)

SELECT  *,  --this is final select to get rows you need with chaines
        (ROW_NUMBER() OVER (ORDER BY (SELECT 1))+2)/3 as seq
FROM cte
WHERE i = 15