Как объединить каждую уникальную запись (на основе 2 столбцов) с каждой записью в другой таблице - PullRequest
0 голосов
/ 02 марта 2012

Это немного сложно объяснить, но я сделаю все возможное.

Скажем, у меня есть две таблицы:

Dates (DateColumn datetime)

SomeData (ID1 int, ID2 int, SomeDate datetime)


Dates ВСЕГДА содержит следующие даты:

1/1/2012
1/2/2012
1/3/2012

SomeData содержит данные, подобные этому:

ID  ID1 ID2 SomeDate
1   1   4   1/1/2012
2   1   4   1/2/2012
3   2   3   1/1/2012
4   2   3   1/3/2012
6   5   1   1/2/2012

Теперь обратите внимание, что в SomeData некоторые строки имеют одинаковые комбинации ID1 и ID2. Также обратите внимание, что некоторым из них не хватает определенных дат, найденных в таблице Dates. Мне нужно как-то объединить каждую из этих комбинаций с КАЖДОЙ датой в таблице Dates, чтобы найти пропущенные даты.

Итак, при присоединении данные выглядят так:

ID      ID1 ID2 SomeDate
1       1   4   1/1/2012
2       1   4   1/2/2012
NULL    1   4   1/3/2012 <-- missing from SomeData table

3       2   3   1/1/2012
NULL    2   3   1/2/2012 <-- missing from SomeData table
4       2   3   1/3/2012

NULL    5   1   1/1/2012 <-- missing from SomeData table
6       5   1   1/2/2012
NULL    5   1   1/3/2012 <-- missing from SomeData table

Обратите внимание, как каждая комбинация ID1 + ID2 возвращает по 3 записи, используя все даты в таблице Dates, а также обратите внимание, как каждая «отсутствующая» запись поддерживает комбинацию ID1 + ID2. Есть идеи, как я могу это осуществить?

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 02 марта 2012
SELECT 
    sd.ID,
    ids.ID1,
    ids.ID2,
    d.DateColumn AS SomeDate
FROM
(
    SELECT DISTINCT ID1, ID2
    FROM SomeData
) ids CROSS JOIN
Dates d LEFT JOIN
SomeData sd 
    ON sd.ID1 = ids.ID1 
    AND sd.ID2 = ids.ID2 
    AND sd.SomeDate = d.DateColumn
1 голос
/ 02 марта 2012

CROSS JOIN ваш друг здесь.Вот полностью проработанный пример

DECLARE @Dates TABLE (DateColumn DATETIME)
INSERT @Dates VALUES ('20120101'), ('20120102'), ('20120103')

DECLARE @SomeData TABLE (ID INTEGER IDENTITY(1,1), ID1 INTEGER, ID2 INTEGER, 
    SomeDate DATETIME)
INSERT @SomeData VALUES (1,4,'20120101'),(1,4,'20120102'),(2,3,'20120101'),
    (2,3,'20120103'), (5,1,'20120102')


SELECT sd2.ID, sd1.ID1, sd1.ID2, d.DateColumn
FROM
(
    SELECT ID1, ID2
    FROM @SomeData
    GROUP BY ID1, ID2
) sd1
    CROSS JOIN @Dates d
    LEFT JOIN @SomeData sd2 ON sd1.ID1 = sd2.ID1 
            AND sd1.ID2 = sd2.ID2 
            AND sd2.SomeDate = d.DateColumn

Итак, чтобы разбить его:

  1. «sd1» подзапрос получает различный набор всех комбинаций ID1 и ID2
  2. Это тогда CROSS APPLY'd к таблице дат.Результатом этого является то, что для каждой комбинации ID1 + ID2 это приведет к тому, что для каждой даты в таблице дат будет возвращена строка
  3. , после чего последний LEFT JOIN попытается сопоставить комбинацию ID1 + ID2 +.Дата для возврата значения идентификатора.Возвращает NULL в качестве идентификатора, если совпадение не найдено, или идентификатора, если оно найдено.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...