SQL Full Outer Join

ELM*_*ELM 1 sql t-sql sql-server-2005 outer-join

我有一个名为'Logs'的表,其中包含以下值:

CheckDate        CheckType        CheckTime
-------------------------------------------
2011-11-25       IN               14:40:00
2011-11-25       OUT              14:45:00
2011-11-25       IN               14:50:00
2011-11-25       OUT              14:55:00
2011-11-25       IN               15:00:00
2011-11-25       OUT              15:05:00
2011-11-25       IN               15:15:00
2011-11-25       OUT              15:20:00
2011-11-25       IN               15:25:00
2011-11-25       OUT              15:30:00
2011-11-25       OUT              15:40:00
2011-11-25       IN               15:45:00
Run Code Online (Sandbox Code Playgroud)

我想使用上一个表来产生以下结果:

CheckDate        CheckIn        CheckOut
-----------------------------------------
2011-11-25       14:40:00       14:45:00
2011-11-25       14:50:00       14:55:00
2011-11-25       15:00:00       15:05:00
2011-11-25       15:15:00       15:20:00
2011-11-25       15:25:00       15:30:00
2011-11-25       NULL           15:40:00
2011-11-25       15:45:00       NULL
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经提出了这个结果集:

CheckDate        CheckIn        CheckOut
-----------------------------------------
2011-11-25       14:40:00       14:45:00
2011-11-25       14:50:00       14:55:00
2011-11-25       15:00:00       15:05:00
2011-11-25       15:15:00       15:20:00
2011-11-25       15:25:00       15:30:00
2011-11-25       15:45:00       NULL
Run Code Online (Sandbox Code Playgroud)

问题是没有CheckIns我无法生成日志:

CheckDate        CheckIn        CheckOut
-----------------------------------------
2011-11-25       NULL           15:40:00
Run Code Online (Sandbox Code Playgroud)

CheckIn - CheckOut配对和顺序的顺序是增加的时间值.

编辑:这是我目前的查询

SELECT Ins.CheckDate,
       Ins.CheckTime,
       Outs.CheckTime

  FROM (SELECT CheckDate,
               CheckTime
          FROM Logs
         WHERE CheckType = 'I') Ins 

  FULL OUTER JOIN

       (SELECT CheckDate,
               CheckTime
          FROM Logs
         WHERE CheckType = 'O') Outs

    ON Ins.CheckDate = Outs.CheckDate AND
       Ins.CheckTime < Outs.CheckTime
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

这应该工作:

;WITH x AS (
   SELECT CheckDate, CheckType, CheckTime
         ,row_number() OVER (ORDER BY CheckDate, CheckTime) As rn
   FROM #t
)
SELECT CASE WHEN x.CheckType = 'IN' OR x.rn = 1 THEN x.CheckDate 
                                               ELSE y.CheckDate END AS CheckDate
      ,CASE WHEN x.CheckType = 'IN'  THEN x.CheckTime ELSE NULL END AS CheckIn
      ,CASE WHEN y.CheckType = 'OUT' THEN y.CheckTime
            WHEN x.CheckType = 'OUT' THEN x.CheckTime ELSE NULL END AS CheckOut
FROM   x
LEFT   JOIN x AS y ON y.rn = x.rn + 1
WHERE  x.CheckType = 'IN'
OR     y.CheckType = 'OUT'
OR     x.rn = 1
Run Code Online (Sandbox Code Playgroud)

它产生了所要求的输出,并涵盖了特殊情况

  • OUT之后是另一个OUT(缺失IN)
  • IN 之后是另一个IN(缺失OUT)
  • IN 什么都没有(最后一行).
  • 第一行以OUT.开头.

尝试data.SE上工作演示.