我有一张表:
Book ¦Time Out ¦Time In
123456789 ¦01/01/2013 ¦07/07/2013
123456788 ¦15/01/2013 ¦20/01/2013
123456788 ¦23/01/2013 ¦30/01/2013
123144563 ¦01/02/2013 ¦18/02/2013
123144563 ¦20/02/2013 ¦NULL
124567892 ¦03/03/2013 ¦10/03/2013
我希望它看起来像这样:
Book ¦Time Out ¦Time In ¦Next Time Out
123456789 ¦01/01/2013 ¦07/07/2013 ¦NULL
123456788 ¦15/01/2013 ¦20/01/2013 ¦23/01/2013
123456788 ¦23/01/2013 ¦30/01/2013 ¦NULL
123144563 ¦01/02/2013 ¦18/02/2013 ¦20/02/2013
123144563 ¦20/02/2013 ¦NULL ¦NULL
124567892 ¦03/03/2013 ¦10/03/2013 ¦NULL
代码:
SELECT nextout.Book,
nextout.[Time In] AS NextTimeIn
FROM BookTable nextout
JOIN BookTable nextoutsec
ON nextout.Book = nextoutsec.Book
WHERE nextout.[Time In] = (SELECT MAX(maxtbl.[Time In])
FROM BookTable maxtbl
WHERE maxtbl.Book = nextout.Book)
这将为重复的图书ID返回相同的“下一次超时”。而不是1个正确的值和1个空值。
谢谢!
答案 0 :(得分:5)
未经测试,但以下内容应该让您入门
;WITH q as (
SELECT Book, [Time In], ROW_NUMBER() OVER (PARTITION BY Book ORDER BY [Time In]) AS rn
FROM BookTable
)
SELECT bt.*, q2.[Time In] AS NextTimeIn
FROM BookTable bt
INNER JOIN q q1 ON q1.Book = bt.Book AND ISNULL(q1.[Time In], 0) = ISNULL(bt.[Time In], 0)
LEFT OUTER JOIN q q2 ON q2.Book = q1.Book AND q2.rn = q1.rn + 1
这个要点是
q
为每本书添加一个行号,按[Time In]
q2
与q1
加入以获得下一个[Time In]
值。q1
与BookTable
加入以获取所有原始值答案 1 :(得分:0)
使用OUTER APPLY:
SELECT BT.*, BT2.TimeOut NextTimeOut
FROM BookTable BT
OUTER APPLY (
SELECT TOP 1 BT2.TimeOut
FROM BookTable BT2
WHERE BT.Book = BT2.Book AND
BT2.TimeOut >= BT.TimeIn
ORDER BY BT2.TimeOut ASC
) BT2
SQLFiddle:http://sqlfiddle.com/#!3/67ff0/3
我不确定:
BT2.TimeOut >= BT.TimeIn
也许它应该是
BT2.TimeOut >= BT.TimeOut
如果同一天有多个TimeIn
/ TimeOut
,它可能会中断(因为您只注册日期,而不是时间)。如果这是一个问题,您可以根据行的id
添加比较。
答案 2 :(得分:0)
性能优于CTE。
<强>查询强>:
select [Book]
,[TimeOut]
,[TimeIn]
,NextTimeOut= case
when [TimeOut]= NextTimeOut then Null
else NextTimeOut
end
from
(select [Book], [TimeOut], [TimeIn]
,(select
max(Timeout) from BookTable B1
where B1.Book=B2.Book
) NextTimeOut
from BookTable B2)a
<强> Result 强>:
| BOOK | TIMEOUT | TIMEIN | NEXTTIMEOUT |
-----------------------------------------------------
| 123456789 | 01/01/2013 | 07/07/2013 | (null) |
| 123456788 | 15/01/2013 | 20/01/2013 | 23/01/2013 |
| 123456788 | 23/01/2013 | 30/01/2013 | (null) |
| 123144563 | 01/02/2013 | 18/02/2013 | 20/02/2013 |
| 123144563 | 20/02/2013 | (null) | (null) |
| 124567892 | 03/03/2013 | 10/03/2013 | (null) |
答案 3 :(得分:0)
您还可以使用相关聚合子查询:
SELECT
this.Book,
this.[Time Out],
this.[Time In],
[Next Time Out] = (
SELECT MIN(next.[Time Out])
FROM BookTable next
WHERE next.Book = this.Book
AND next.[Time Out] > this.[Time Out]
)
FROM BookTable this
;
这可以被视为@xanatos's suggestion的变体,但可能会变得更轻量级。