SQL левое соединение (условие множественного соединения) - PullRequest
9 голосов
/ 20 октября 2011

У меня есть две производные таблицы с именами Check In и Check Out

Check Ins

CheckDate  CheckIn
---------- ---------
08/02/2011 10:10:03
08/02/2011 15:57:16
07/19/2011 13:58:52
07/19/2011 16:50:55
07/26/2011 15:11:24
06/21/2011 12:36:47
08/16/2011 14:49:36
08/09/2011 13:52:10
08/09/2011 16:54:51
08/23/2011 15:48:58
09/06/2011 15:23:00
09/13/2011 10:09:27
09/13/2011 10:40:14
09/13/2011 11:43:14
09/13/2011 11:59:32
09/13/2011 17:05:24
09/20/2011 11:03:42
09/20/2011 12:08:50
09/20/2011 15:21:06
09/20/2011 15:34:29
09/27/2011 11:34:06
10/04/2011 11:37:59
10/04/2011 15:24:04
10/04/2011 16:57:44
10/11/2011 18:19:33

Check Out

CheckDate  CheckOut
---------- ---------
08/02/2011 13:29:40
08/02/2011 17:02:25
07/12/2011 17:06:06
07/19/2011 16:40:15
07/19/2011 17:07:35
07/26/2011 14:48:10
07/26/2011 17:27:08
05/31/2011 17:01:39
06/07/2011 17:04:29
06/14/2011 17:08:50
06/21/2011 17:03:46
06/28/2011 17:10:45
07/05/2011 17:02:48
08/16/2011 13:37:36
08/16/2011 17:06:34
08/09/2011 12:00:29
08/09/2011 13:29:36
08/09/2011 14:36:09
08/09/2011 17:00:38
08/23/2011 13:37:11
08/23/2011 17:01:37
09/06/2011 17:00:09
09/13/2011 10:11:50
09/13/2011 11:22:02
09/13/2011 11:47:35
09/13/2011 14:13:36
09/13/2011 14:14:25
09/13/2011 17:08:43
09/20/2011 09:54:55
09/20/2011 11:55:31
09/20/2011 11:55:36
09/20/2011 13:35:16
09/20/2011 15:26:02
09/20/2011 16:33:21
09/20/2011 17:07:52
09/27/2011 11:12:38
10/04/2011 13:26:31
10/04/2011 16:32:56
10/04/2011 17:02:35
10/11/2011 18:25:32

Я хочу связать входы с проверками при условии, что оба журнала находятся на одной и той же дате, а значения извлечения не могут быть раньше, чем проверки, поэтому я пришел к этому запросу

  SELECT A.ChkDt
      AS CheckDate,
         B.CheckIn,
         MIN(A.ChkTm)
      AS CheckOut
    FROM #tempAttLogs
      AS A LEFT JOIN
         (SELECT ChkDt
              AS CheckDate,
                 MIN(ChkTm)
              AS CheckIn
            FROM #tempAttLogs
           WHERE ChkTp = 'I'
        GROUP BY ChkDt) B
      ON A.ChkDt = B.CheckDate
   WHERE ChkTp = 'O' AND
         A.ChkTm > B.CheckIn
GROUP BY A.ChkDt, B.CheckIn

С результирующим набором

CheckDate  CheckIn   CheckOut
---------- --------- ---------
06/21/2011 12:36:47  17:03:46
07/19/2011 13:58:52  16:40:15
07/26/2011 15:11:24  17:27:08
08/02/2011 10:10:03  13:29:40
08/09/2011 13:52:10  14:36:09
08/16/2011 14:49:36  17:06:34
08/23/2011 15:48:58  17:01:37
09/06/2011 15:23:00  17:00:09
09/13/2011 10:09:27  10:11:50
09/20/2011 11:03:42  11:55:31
10/04/2011 11:37:59  13:26:31
10/11/2011 18:19:33  18:25:32

Дело в том, что я также хочу включить журналы без соответствующих пар. Как это может быть возможно?

EDIT

Мой ожидаемый набор результатов должен включать журналы, подобные этому

CheckDate  CheckIn   CheckOut
---------- --------- ---------
05/23/2011 NULL      17:04:27

Ответы [ 3 ]

8 голосов
/ 20 октября 2011

Вы можете переместить любой предикат, ссылающийся на правую таблицу, в предложение ON вместо WHERE, чтобы избежать превращения JOIN в INNER JOIN

, например,

ON A.ChkDt = B.CheckDate AND
         A.ChkTm > B.CheckIn
WHERE ChkTp = 'O'

Вместо

    ON A.ChkDt = B.CheckDate
   WHERE ChkTp = 'O' AND
         A.ChkTm > B.CheckIn
2 голосов
/ 20 октября 2011

Включите нулевые значения в ваше предложение WHERE Пример:

WHERE( ChkTp = 'O' AND
         A.ChkTm > B.CheckIn) OR B.CheckDate IS NULL
0 голосов
/ 20 октября 2011

Это может быть полезно (не проверено) для решения вашей проблемы, хотя оно слегка касается вашего вопроса.

select 
  Checkdate, CheckIn as CheckTime, 'I' as CheckAction
from CheckIns 

union all

select 
  Checkdate, CheckOut as CheckTime, 'O' as CheckAction
from CheckOuts
order by 1,2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...