Как я могу определить различия записей между двумя таблицами? - PullRequest
1 голос
/ 18 ноября 2011

У меня два запроса.Первый запрос:

select in_gentime
from in_time_temp
where cardnumber = 'MCL1570'
order by in_gentime

Вывод:

2011-10-11 08:06:00.000
2011-10-12 08:35:00.000
2011-10-13 08:21:00.000
2011-10-15 08:21:00.000
2011-10-16 08:21:00.000
2011-10-17 08:21:00.000
2011-10-18 08:21:00.000
2011-10-19 08:21:00.000
2011-10-20 08:21:00.000
2011-10-21 08:21:00.000
2011-10-22 08:21:00.000
2011-10-24 08:21:00.000
2011-10-25 08:21:00.000
2011-10-26 09:00:00.000
2011-10-27 09:00:00.000
2011-10-28 09:00:00.000
2011-10-29 09:00:00.000
2011-10-31 09:00:00.000

Второй запрос:

select out_gentime
from out_time_temp
where cardnumber = 'MCL1570'
order by out_gentime

Вывод:

2011-10-11 22:02:00.000
2011-10-12 21:14:00.000
2011-10-14 21:59:00.000
2011-10-15 21:59:00.000
2011-10-16 21:59:00.000
2011-10-17 21:59:00.000
2011-10-18 21:59:00.000
2011-10-19 21:59:00.000
2011-10-20 21:59:00.000
2011-10-21 21:59:00.000
2011-10-22 21:59:00.000
2011-10-24 21:59:00.000
2011-10-25 21:59:00.000
2011-10-26 18:15:00.000
2011-10-27 18:15:00.000
2011-10-28 18:15:00.000
2011-10-29 23:15:00.000
2011-10-31 22:15:00.000

Мне нужно идентифицировать записи, которые имеют DATE значения, которые появляются в одной таблице, но не в другой.Я хочу игнорировать конкретные TIME.Например, я хочу вернуть только эти 2 записи:

2011-10-13 08:21:00.000
2011-10-14 21:59:00.000 

Как мне написать запрос для этого?

Ответы [ 4 ]

2 голосов
/ 18 ноября 2011

Если вы используете FULL OUTER JOIN, вы можете объединить список дат, а затем просто выбрать записи, в которых одна или другая имеет значение NULL:

SELECT COALESCE(i.in_gentime, o.out_gentime)  -- pick first non-null value
FROM in_time_temp i
FULL OUTER JOIN out_time_temp o 
    ON  CAST(CONVERT(varchar(8), i.in_gentime,  112) AS datetime) = 
        CAST(CONVERT(varchar(8), o.out_gentime, 112) AS datetime)
    AND i.cardnumber = o.cardnumber
WHERE (i.in_gentime is null or o.out_gentime IS NULL)
AND   (i.cardnumber = 'MCL1750' OR o.cardnumber = 'MCL1750')

Обновление .Натан, вот полный тестовый код, я не уверен, почему вы не получаете результаты, но при запуске я получаю 4 записи:

CREATE TABLE in_time_temp  
(
    in_gentime   datetime,
    cardnumber   nvarchar(50)
)
insert into in_time_temp values('2011-10-11 08:06:00.000', 'MCL1750')
insert into in_time_temp values('2011-10-12 08:35:00.000', 'MCL1750')
insert into in_time_temp values('2011-10-13 08:21:00.000', 'MCL1750')
insert into in_time_temp values('2011-10-15 08:21:00.000', 'MCL1750')
insert into in_time_temp values('2011-10-16 08:21:00.000', 'MCL1750')
insert into in_time_temp values('2011-10-17 08:21:00.000', 'MCL1750')


CREATE TABLE out_time_temp
(
    out_gentime    datetime,
    cardnumber   nvarchar(50)
)
insert into out_time_temp values('2011-10-11 22:02:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-12 21:14:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-14 21:59:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-15 21:59:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-16 21:59:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-17 21:59:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-18 21:59:00.000', 'MCL1750')
insert into out_time_temp values('2011-10-19 21:59:00.000', 'MCL1750')


SELECT COALESCE(i.in_gentime, o.out_gentime)  -- pick first non-null value
FROM in_time_temp i
FULL OUTER JOIN out_time_temp o 
    ON  CAST(CONVERT(varchar(8), i.in_gentime,  112) AS datetime) = 
        CAST(CONVERT(varchar(8), o.out_gentime, 112) AS datetime)
    AND i.cardnumber = o.cardnumber
WHERE (i.in_gentime is null or o.out_gentime IS NULL)
AND   (i.cardnumber = 'MCL1750' OR o.cardnumber = 'MCL1750')

И вывод:

2011-10-13 08:21:00.000
2011-10-14 21:59:00.000
2011-10-18 21:59:00.000
2011-10-19 21:59:00.000
2 голосов
/ 18 ноября 2011

как то так ...

select in_gentime as THETIME from in_time_temp where cardnumber = 'MCL1570' 
 and in_gentime not in 
(select out_gentime from out_time_temp where cardnumber = 'MCL1570')
union
select out_gentime  as THETIME from out_time_temp where cardnumber = 'MCL1570'
 and out_gentime not in 
(select in_gentime as THETIME from in_time_temp where cardnumber = 'MCL1570' )
order by THETIME

Это должно дать вам все уникальные предметы по двум таблицам.

1 голос
/ 18 ноября 2011

Это должно предоставить вам время, указанное в одной из двух таблиц:

SELECT CASE
          WHEN in_gentime IS NOT NULL THEN in_gentime
          ELSE out_gentime
       END AS THETIME
FROM in_time_temp AS i
FULL OUTER JOIN out_time_temp AS out ON i.cardnumber = out.cardnumber
   AND i.in_gentime = out.out_gentime
WHERE i.in_gentime IS NULL
   OR out.i_gentime IS NULL
order by in_gentime

Если вы хотите сослаться только на часть DATE, а не TIME, этот ответ здесь (Как и в случае с JohnD, самое большое отличие - это использование CASE и его (вероятно, более эффективное) использование COALESCE)

SELECT CASE
          WHEN i.in_gentime IS NOT NULL THEN i.in_gentime
          ELSE o.out_gentime
       END AS THETIME
FROM in_time_temp AS i
FULL OUTER JOIN out_time_temp AS o ON i.cardnumber = o.cardnumber
   AND CAST(CONVERT(VARCHAR(8), i.in_gentime, 112) AS DATETIME) =
      CAST(CONVERT(VARCHAR(8), o.out_gentime, 112) AS DATETIME)
WHERE i.in_gentime IS NULL
   OR o.out_gentime IS NULL
order by i.in_gentime
0 голосов
/ 18 ноября 2011
select in_gentime
from in_time_temp
where cardnumber = 'MCL1570' and
      dateadd(day, datediff(day, 0, in_gentime), 0) not in
        (select dateadd(day, datediff(day, 0, out_gentime), 0)
         from out_time_temp 
         where cardnumber = 'MCL1570')
union all         
select out_gentime
from out_time_temp
where  cardnumber = 'MCL1570' and
      dateadd(day, datediff(day, 0, out_gentime), 0) not in
        (select dateadd(day, datediff(day, 0, in_gentime), 0)
         from in_time_temp 
         where cardnumber = 'MCL1570')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...