2

我有一张像这样的桌子:

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 个空值。

谢谢你!

4

4 回答 4

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以获取所有原始值
于 2013-08-08T10:43:08.840 回答
0

通过使用外部应用:

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行的比较。

于 2013-08-08T10:44:25.913 回答
0

SQL小提琴

具有比 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

结果

|      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) |
于 2013-08-08T11:14:30.533 回答
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 建议的变体,但结果可能更轻量级。

于 2013-08-09T19:31:57.490 回答