我在Sql Sever 2005中有一个表:
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:00.000
预期输出:需要与输入日期相邻(最接近)的最小和最大日期时间...
也需要通过eid进行分组。
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 :(得分: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。
答案 1 :(得分: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
答案 2 :(得分: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!
答案 3 :(得分: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