2013-11-20 73 views
1

我有一個表在SQL Sever的2005:SQL服務器 - 需要的最小和最大日期時間相鄰(最近)輸入日期

id eid name  datetime 
-- |----|------- |------------------------ 
1 | 1 | john | 2013-11-18 15:30:00.000 
2 | 1 | john | 2013-11-18 14:10:00.000 
3 | 1 | john | 2013-11-18 13:30:00.000 
4 | 1 | john | 2013-11-18 16:00:00.000 
5 | 1 | john | 2013-11-18 17:00:00.000 
6 | 2 | Richard| 2013-11-18 13:40:00.000 
7 | 2 | Richard| 2013-11-18 16:20:00.000 
8 | 3 | Mandy | 2013-11-18 20:22:00.000 
9 | 3 | Mandy | 2013-11-18 20:20:00.000 
10| 4 | Micheal| 2013-11-18 13:00:00.000 

輸入將是一個日期,例如 - 2013-11-18 15: 50:也需要需要最小和相鄰的(最近的),以輸入的日期的日期時間的最大...
分組通過EID:00.000
的預期輸出。

id eid name  AdjacentMinimumDateTime AdjacentMaximumDateTime 
-- |----|------- |---------------------------|------------------------ 
1 | 1 | john | 2013-11-18 15:30:00.000 | 2013-11-18 16:00:00.000 
6 | 2 | Richard| 2013-11-18 13:40:00.000 | 2013-11-18 16:20:00.000 
8 | 3 | Mandy | NULL      | 2013-11-18 20:20:00.000 
9 | 4 | Micheal| 2013-11-18 13:00:00.000 | NULL 
+0

這是沒有意義的'id' ... –

+0

ID在我需要的情況下,我做到了由join.Anyways感謝的幫助下返回 – Fnk

回答

2

試試這個:

WITH 
BEFORE AS (
    SELECT eid, max(datetime) date FROM t 
    WHERE datetime <= '2013-11-18 15:50:00.000' 
    GROUP BY eid 
), 
AFTER AS (
    SELECT eid, min(datetime) date FROM t 
    WHERE datetime >= '2013-11-18 15:50:00.000' 
    GROUP BY eid 
) 
SELECT t.eid, t.name, max(b.date) beforeDate, min(a.date) afterDate FROM t 
LEFT JOIN BEFORE b ON t.eid = b.eid 
LEFT JOIN AFTER a ON t.eid = a.eid 
GROUP BY t.eid, t.name 
ORDER BY t.eid 

或非-CTE版本:

SELECT t.eid, t.name, max(b.date) beforeDate, min(a.date) afterDate FROM t 
LEFT JOIN (
    SELECT eid, max(datetime) date FROM t 
    WHERE datetime <= '2013-11-18 15:50:00.000' 
    GROUP BY eid 
) b ON t.eid = b.eid 
LEFT JOIN (
    SELECT eid, min(datetime) date FROM t 
    WHERE datetime >= '2013-11-18 15:50:00.000' 
    GROUP BY eid 
) a ON t.eid = a.eid 
GROUP BY t.eid, t.name 
ORDER BY t.eid 

我已經添加了重複日期以測試它是否適用於它們。

輸出:

| EID | NAME |     BEFOREDATE |     AFTERDATE | 
|-----|---------|----------------------------|----------------------------| 
| 1 | john | November, 18 2013 15:30:00 | November, 18 2013 16:00:00 | 
| 2 | Richard | November, 18 2013 13:40:00 | November, 18 2013 16:20:00 | 
| 3 | Mandy |      (null) | November, 18 2013 20:20:00 | 
| 4 | Michael | November, 18 2013 13:00:00 |      (null) | 
| 5 | Mosty | November, 18 2013 15:00:00 | November, 18 2013 16:00:00 | 

小提琴here

0

嘗試......

SELECT 
    MIN(id) [id], 
    eid, 
    name, 
    (SELECT MAX(datetime) FROM table t1 WHERE t1.datetime < inputdate 
     AND t1.eid = t.eid) [AdjacentMinimumDateTime], 
    (SELECT MIN(datetime) FROM table t2 WHERE t2.datetime > inputdate 
     AND t2.eid = t.eid) [AdjacentMaximumDateTime] 
FROM table t 
GROUP BY t.id, t.Name 
0

嘗試我的。它的工作原理

declare @TestTable table (ID int, eid int, Name varchar(10), TestDate datetime) 
declare @InputDate datetime = '2013-11-18 15:50:00.000' 

insert into @TestTable (ID,eid,Name,TestDate) 
values (1,1,'john', '2013-11-18 15:30:00.000') 
     ,(2,1,'john', '2013-11-18 14:10:00.000') 
     ,(3,1,'john', '2013-11-18 13:30:00.000') 
     ,(4,1,'john', '2013-11-18 16:00:00.000') 
     ,(5,1,'john', '2013-11-18 17:00:00.000') 
     ,(6,2,'richard', '2013-11-18 13:40:00.000') 
     ,(7,2,'richard', '2013-11-18 16:20:00.000') 
     ,(8,3,'mandy', '2013-11-18 20:22:00.000') 
     ,(9,3,'mandy', '2013-11-18 20:20:00.000') 
     ,(10,4,'michael', '2013-11-18 13:00:00.000'); 


with cte as 
(
select id, eid, name, TestDate, (datediff(s, TestDate, @InputDate)) as DateDiffSeconds 
from @TestTable 
) 

select cte.eid, cte.name, x.testdate as maxunder, y.testdate as minover,   @InputDate as InputDateForComparison 
from cte 
left join 
(
      select eid, testdate 
      from cte 

     join ( 
        select eid as eidmin, min(DateDiffSeconds) as datematchunder 
        from cte 
        where DateDiffSeconds >= 0 
        group by eid 

       ) as datematchunder on datematchunder.datematchunder = cte.DateDiffSeconds 

) x on x.eid = cte.eid 

left join 
(
      select eid, testdate 
     from cte 

     join ( 
        select eid as eidmin, max(DateDiffSeconds) as datematchover 
        from cte 
        where DateDiffSeconds <= 0 
        group by eid 

       ) as datematchover on datematchover.datematchover = cte.DateDiffSeconds 

) y on y.eid = cte.eid 

group by cte.eid, cte.name, x.testdate, y.testdate; 

BAM!

0

開始通過尋找一個之前和之後的一個,那麼你可以將它們組合成一個單一的查詢,如果你喜歡:

declare @TestTable table (ID int, eid int, Name varchar(10), TestDate datetime) 
declare @InputDate datetime = '2013-11-18 15:50:00.000' 

insert into @TestTable (ID,eid,Name,TestDate) 
values (1,1,'john', '2013-11-18 15:30:00.000') 
     ,(2,1,'john', '2013-11-18 14:10:00.000') 
     ,(3,1,'john', '2013-11-18 13:30:00.000') 
     ,(4,1,'john', '2013-11-18 16:00:00.000') 
     ,(5,1,'john', '2013-11-18 17:00:00.000') 
     ,(6,2,'richard', '2013-11-18 13:40:00.000') 
     ,(7,2,'richard', '2013-11-18 16:20:00.000') 
     ,(8,3,'mandy', '2013-11-18 20:22:00.000') 
     ,(9,3,'mandy', '2013-11-18 20:20:00.000') 
     ,(10,4,'michael', '2013-11-18 13:00:00.000'); 

SELECT * 
FROM @TestTable 
ORDER BY TestDate 

--get the one previous 
SELECT TOP 1 * 
FROM @TestTable 
WHERE TestDate < @InputDate 
ORDER BY TestDate desc 

--get the one after 
SELECT TOP 1 * 
FROM @TestTable 
WHERE TestDate > @InputDate 
ORDER BY TestDate