Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
Дано:
Таблица оборудования, в ней поля: Id, Название.
Таблица выработки, при создании единицы продукции в нее помещается новая запись с Id_станка на котором собрали.

Я хочу выбрать распределение выработки по станкам, в т. ч. и тем станкам, по которым выработка отсутствует.

Т. е. если есть станок 1 с выр-кой 10, станок 2 с выр-кой 15 и станок 3 с выр-кой 0 я делаю запрос

Select Оборудование.Id, Оборудование.Название, Count(Выработка.Id) From Оборудование
Left Join Выработка on Оборудование.Id=Выработка.Id_Оборудование
Group By  Оборудование.Id, Оборудование.Название


Получаю, как и написано в инструкции к Join, результат вида:
1 "Станок 1" 10
2 "Станок 2" 15
3 "Станок 3" 0

Но если я добавлю к правой таблице условие, например

Select Оборудование.Id, Оборудование.Название, Count(Выработка.Id) From Оборудование
Left Join Выработка on Оборудование.Id=Выработка.Id_Оборудование
Where Выработка.Время>'2018.01.01'
Group By  Оборудование.Id, Оборудование.Название


То я уже получаю результат вида:
1 "Станок 1" 10
2 "Станок 2" 15

Меня это не устраивает. Как обойти?
20 ноя 18, 13:56    [21739096]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Beltar,

предикат в ON перенести. Вы сейчас получаете INNER JOIN
20 ноя 18, 13:59    [21739103]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7383
Beltar,

Надо накладывать не общий фильтр на выборку, в только на таблицу, в которой происходит объединение. Т.е. where заменить на and.
20 ноя 18, 14:01    [21739109]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
Переписал в виде

Select Оборудование.Id, Оборудование.Название, Count(Выработка.Id) From Оборудование
Left Join Выработка on (Оборудование.Id=Выработка.Id_Оборудование and Выработка.Время>'2018.01.01')
Group By  Оборудование.Id, Оборудование.Название


Спс большое.
20 ноя 18, 14:05    [21739118]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Владислав Колосов
Beltar,

Надо накладывать не общий фильтр на выборку, в только на таблицу, в которой происходит объединение. Т.е. where заменить на and.
Или добавить в WHERE ... OR Выработка.Id IS NULL.

Кстати, а что должен вернуть COUNT()? Каковы ваши ожидания?
20 ноя 18, 15:56    [21739291]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
Количество записей для каждого Id_Оборудования.

автор
Выработка.Id IS NULL.


Id - первичный ключ.
20 ноя 18, 16:34    [21739363]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Beltar
Количество записей для каждого Id_Оборудования.

автор
Выработка.Id IS NULL.


Id - первичный ключ.

Приборы?
300!
20 ноя 18, 16:35    [21739365]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Beltar
Количество записей для каждого Id_Оборудования.
Надеюсь, игнорирование Выработка.Id IS NULL - это то, что вам нужно?
20 ноя 18, 21:52    [21739535]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Beltar
Количество записей для каждого Id_Оборудования.

автор
Выработка.Id IS NULL.


Id - первичный ключ.
LEFT JOIN возвращает все поля правой таблицы равными NULL, если подходящая строка не найдена.
PK в этом случае ничего не значит.
20 ноя 18, 21:54    [21739536]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
Может в других БД это не так, но у меня возвращает 0. Наверное, потому, что используется Count и отсутствие записей - это не некая пустота, а вполне конкретное нулевое их количество. Если вы про это.
20 ноя 18, 23:18    [21739563]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Beltar
Может в других БД это не так, но у меня возвращает 0. Наверное, потому, что используется Count и отсутствие записей - это не некая пустота, а вполне конкретное нулевое их количество. Если вы про это.
COUNT(*) и COUNT(<Expression>) работают по-разному и дают разный результат.
Expression IS NULL COUNT(<Expression>) игнорирует. А COUNT(*) считает всё.
21 ноя 18, 10:12    [21739726]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
iap, я мог бы записать, например, так:

Select Count(СменнаяВыработка.*) From СменнаяВыработка


Точнее, я так и хотел, но "Incorrect syntax near '*'".
21 ноя 18, 12:01    [21739884]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Beltar
iap, я мог бы записать, например, так:

Select Count(СменнаяВыработка.*) From СменнаяВыработка


Точнее, я так и хотел, но "Incorrect syntax near '*'".

вы хелп принципиально не открываете?
21 ноя 18, 12:01    [21739886]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
Я иду что-то спрашивать только после того, как не нашел ни черта не в хелпе, ни в сети.
21 ноя 18, 12:49    [21739950]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
Beltar
Я иду что-то спрашивать только после того, как не нашел ни черта не в хелпе, ни в сети.

и где написано, что писать Count(СменнаяВыработка.*) вообще допустимо?
21 ноя 18, 12:57    [21739961]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
Beltar
Member

Откуда:
Сообщений: 199
 Select Count(СменнаяВыработка.*) From СменнаяВыработка


Что недопустимо.

И

 Select Count(*) From СменнаяВыработка


Что допустимо.

Синтаксически эквивалентны. Должны быть.

Я не особо понимаю SQL, и использую его только для запросов из других программ, но, блин, ИмяТаблицы.ИмяПоля=ИмяПоля, если нет неопределенностей. Если они есть, то ИмяТаблицы становится обязательным.

Count(*) и Count(Id) тоже должны быть эквивалентны, если Id является первичным ключом, а значит не может быть NULL по определению.
21 ноя 18, 14:13    [21740076]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Beltar
Синтаксически эквивалентны. Должны быть.
Это вы сами придумали.
Вообще-то, можно считать, что COUNT(*) и COUNT(Expression) - разные функции.
Звёздочку по всей видимости здесь можно воспринимать как часть имени (подобно, например, слову "MAX" в VARCHAR(MAX)).
21 ноя 18, 14:29    [21740108]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
Beltar
Count(*) и Count(Id) тоже должны быть эквивалентны, если Id является первичным ключом, а значит не может быть NULL по определению.
В таблице не может.
А в запросе ещё как может!
Пример вы сами привели своим запросом с LEFT JOIN
21 ноя 18, 14:32    [21740119]     Ответить | Цитировать Сообщить модератору
 Re: Left Join и условие по правой таблице  [new]
iap
Member

Откуда: Москва
Сообщений: 46951
iap
Beltar
Count(*) и Count(Id) тоже должны быть эквивалентны, если Id является первичным ключом, а значит не может быть NULL по определению.
В таблице не может.
А в запросе ещё как может!
Пример вы сами привели своим запросом с LEFT JOIN
Может быть, вы считаете, что COUNT(ПолеТаблицы) считает какие-то там поля таблицы?
Однако, COUNT() всегда считает количество строк!
21 ноя 18, 14:35    [21740128]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить