简体   繁体   English

SQL全外连接

[英]SQL Full Outer Join

I have a table named 'Logs' with the following values : 我有一个名为“ 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

I want to use the previous table to produce a result of: 我想使用上一个表来产生以下结果:

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

So far I have come up with this result set : 到目前为止,我已经提出了以下结果集:

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

The problem is I cannot generate the log without CheckIns : 问题是没有CheckIns我无法生成日志:

CheckDate        CheckIn        CheckOut
-----------------------------------------
2011-11-25       NULL           15:40:00

The sequence of CheckIn - CheckOut pairing and order is in increasing time value. CheckIn-CheckOut配对和顺序的顺序是增加时间值。

EDIT : This is my current query 编辑:这是我当前的查询

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

This should work: 这应该工作:

;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

It produces exactly the output requested and covers special cases where 它会精确地产生所需的输出,并涵盖特殊情况,其中

  • OUT is followed by another OUT (missing IN ) OUT之后是另一个OUT (缺少IN
  • IN is followed by another IN (missing OUT ) IN之后是另一个IN (缺少OUT
  • IN is followed by nothing (last row). IN后面没有任何内容(最后一行)。
  • first row starts with OUT . 第一行以OUT开头。

Try the working demo on data.SE . 尝试在data.SE上运行的演示

Some of the optimizers doesn't support "FULL OUTER JOIN" of sql So, Query should be: 一些优化器不支持sql的“ FULL OUTER JOIN”,因此查询应该是:

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

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

  LEFT OUTER JOIN

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

    ON Ins.CheckDate = Outs.CheckDate AND
       Ins.CheckTime < Outs.CheckTime

UNION

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

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

  RIGHT OUTER JOIN

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

    ON Ins.CheckDate = Outs.CheckDate AND
       Ins.CheckTime < Outs.CheckTime

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM