SQL Join не возвращает то, что я ожидаю - PullRequest
2 голосов
/ 21 января 2009

У меня есть временная таблица, в которой я создаю запрос в следующем формате. Он содержит запись для каждого идентификатора клиента, года и месяца за несколько лет.

# * T * 1003 Клиент | CustomerID | Год | Месяц ех. Foo | 12345 | 2008 | 12 Foo | 12345 | 2008 | 11 Bar | 11224 | 2007 | 7 Когда я присоединяю эту временную таблицу к другой таблице следующего формата, я получаю намного больше результатов, чем ожидаю. Событие

EventID | CustomerID | DateOpened

ех.

1100 | 12345 | '2008-12-11 10:15:43'
1100 | 12345 | '2008-12-11 11:25:17'

Я пытаюсь получить результирующий набор количества событий вместе с такими как Клиент, Год и Месяц.

SELECT COUNT(EventID), Customer, Year, Month
FROM [Event] 
JOIN #T ON [Event].CustomerID = #T.CustomerID
WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
GROUP BY Customer, Year, Month
ORDER BY Year, Month

Я получаю записи за каждый год и месяц, а не только за декабрь 2008 года.

Ответы [ 4 ]

2 голосов
/ 21 января 2009

Вы указываете дату в таблице событий, но не в соединении - поэтому она объединяет все записи из временной таблицы с совпадающей привязкой.

Попробуйте это:

SELECT COUNT(e.EventID), T.Customer, T.Year, T.Month
FROM [Event] e
INNER JOIN #T T ON (
  T.CustomerID = e.CustomerID and 
  T.Year = year(e.DateOpened) and 
  T.Month = month(e.DateOpened) 
  ) 
WHERE T.Year = 2008 
  and T.Month = 12 
GROUP BY T.Customer, T.Year, T.Month
ORDER BY T.Year, T.Month
2 голосов
/ 21 января 2009

Возможно, вы имеете в виду:

SELECT COUNT(EventID)
    ,Customer
    ,Year
    ,Month
FROM [Event] 
INNER JOIN #T
    ON [Event].CustomerID = #T.CustomerID
    AND YEAR([Event].DateOpened) = #T.YEAR
    AND MONTH([Event].DateOpened) = #T.MONTH
WHERE [Event].DateOpened >= '2008-12-01'
    AND [Event].DateOpened < '2009-01-01'
GROUP BY Customer
    ,Year
    ,Month
ORDER BY Year
    ,Month

Обратите внимание, я исправил еще одну скрытую ошибку в вашем коде: ваш BETWEEN собирается исключить даты, такие как '2008-12-31 10:15:43' Вы можете использовать эту или аналогичную технику.

1 голос
/ 21 января 2009

Проблема в том, что в #T есть две строки с CustomerID = 12345. Каждая из этих строк соединяется с каждой из строк в Event. Если вы хотите, чтобы CustomerID был указан только в декабре, вам также нужно отфильтровать #T:

SELECT COUNT(EventID), Customer, Year, Month
    FROM [Event] 
    JOIN #T ON [Event].CustomerID = #T.CustomerID
    WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
      AND #T.Year = 2008
      AND #T.Month = 12
    GROUP BY Customer, Year, Month
    ORDER BY Year, Month

Если у вас есть другие ожидания, вам лучше уточнить ваш вопрос.

0 голосов
/ 21 января 2009

Это показывает, что #T имеет избыточную информацию, если вы хотите только имя клиента.

Вы можете решить это с помощью подзапроса

SELECT COUNT(EventID), (select TOP 1 #T.Customer from #T Where #T.CustomerID = [Event].CustomerID ), Year, Month
FROM [Event] 
WHERE [Event].DateOpened BETWEEN '2008-12-01' AND '2008-12-31'
GROUP BY CustomerID, Year, Month
ORDER BY Year, Month
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...