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

Откуда:
Сообщений: 55
Добрый день!

Вывожу клиентов, которые в определенные периоды не заказывали (пример упрощен).
В результате нет строк, хотя по идее должны быть. Где ошибся?

SELECT p.IdPeriod
	,p.IdCust
	,0 As Summ
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
WHERE 
	o.IdCust is null



версия сервера Microsoft SQL Server 2008 R2 (SP1) - 10.50.2550.0 (X64)
19 окт 12, 15:19    [13347354]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
mottura
В результате нет строк, хотя по идее должны быть

кому должны? где исходные данные? нужна угадывать что у вас в таблице?
19 окт 12, 15:21    [13347373]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
mottura,

лишнее
WHERE 
	o.IdCust is null
19 окт 12, 15:40    [13347556]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
RubinDm
Member

Откуда:
Сообщений: 461
trew
mottura,

лишнее
WHERE 
	o.IdCust is null

не лишнее.

по идее, должно работать. что там с данными в тбличках?
19 окт 12, 15:45    [13347596]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
RubinDm
Member

Откуда:
Сообщений: 461
вот еще те же яйцы.
SELECT p.IdPeriod, p.IdCust, 0 As Summ
FROM PointPeriod p
where not exists
  ( select * from [Order] o
    where o.IdCust = p.IdCust
       and p.PeriodFrom <= o.DateOrder and o.DateOrder <= p.PeriodTo
  )
19 окт 12, 15:49    [13347614]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
mottura
Где ошибся?
"пример упрощен"
19 окт 12, 15:52    [13347645]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

Откуда:
Сообщений: 55
Knyazev Alexey,

Да, понятно что инфы мало, полагал что может в коде есть явная ошибка.
Пример вымышлен и упрощен.

Таблица PointPeriod - это выборка. Выдает 60 записей

При запросе:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
WHERE 
	o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'
GROUP BY p.IdPeriod
          ,p.IdCust
          ,p.PeriodFrom
          ,p.PeriodTo


Выдает 32 записи.

А мне нужно получить все 60 записей.
Решил вытащить недостающие 28 записей запросом из первого поста, но пусто.
В таблице [Order] существуют записи для недостающий [IdCust], которые не попадают в рамки (от '20121001' до '20121019'), но они мне не нужны.

В результате нужно получить следующее:
IdPeriod IdCust Days
101 28 0
102 175 12
102 430 0
103 52t 20
104 39 0
151 135 0
151 95 19
460 1 0
19 окт 12, 15:57    [13347685]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

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

да, это возможно

Я воссоздал ситуацию в среде ms access - там всё работает без вопросов.
В ms sql - затык.
19 окт 12, 16:02    [13347722]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

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

с этим я тоже пробовал - записей нема
видно что-то я упустил в своих упрощениях
19 окт 12, 16:03    [13347730]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
mottura
iap,

да, это возможно

Я воссоздал ситуацию в среде ms access - там всё работает без вопросов.
В ms sql - затык.
Ну так Ваше упрощение "выплеснуло с водой ребёнка"!
Упрощать тоже надо правильно
19 окт 12, 16:05    [13347737]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
mottura
Таблица PointPeriod - это выборка. Выдает 60 записей

При запросе:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
WHERE 
	o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'
GROUP BY p.IdPeriod
          ,p.IdCust
          ,p.PeriodFrom
          ,p.PeriodTo



Выдает 32 записи.

А мне нужно получить все 60 записей.
Решил вытащить недостающие 28 записей запросом из первого поста, но пусто.
Почему бы сразу не вытащить "все 60 записей", без отдельного вытаскивания "недостающие 28 записей "?
Просто переместите "WHERE o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'" в условие джойна
19 окт 12, 16:11    [13347769]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
Kopilogus
Member

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

Сколько записей выдает запрос:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
19 окт 12, 16:17    [13347810]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

Откуда:
Сообщений: 55
alexeyvg
mottura
Таблица PointPeriod - это выборка. Выдает 60 записей

При запросе:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
WHERE 
	o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'
GROUP BY p.IdPeriod
          ,p.IdCust
          ,p.PeriodFrom
          ,p.PeriodTo



Выдает 32 записи.

А мне нужно получить все 60 записей.
Решил вытащить недостающие 28 записей запросом из первого поста, но пусто.
Почему бы сразу не вытащить "все 60 записей", без отдельного вытаскивания "недостающие 28 записей "?
Просто переместите "WHERE o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'" в условие джойна


Да, получил все записи. Спасибо!

С первый запросом остался вопрос. Но он стал не актуален )
19 окт 12, 16:24    [13347858]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

Откуда:
Сообщений: 55
Kopilogus
mottura,

Сколько записей выдает запрос:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo


Если добавить GROUP BY, то 60
Всем спасибо
19 окт 12, 16:28    [13347900]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
RubinDm
Member

Откуда:
Сообщений: 461
SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo
        -- если в [Order] не нашлось записи, которая удовлетворяла бы условиям джойна,
        -- то джойн какбэ выдаст единственную строку, и в каждой колонке этой строки будет NULL
WHERE 
	o.DateOrder >= '20121001' AND o.DateOrder <= '20121019'
        -- тут вы снова (зачем-то) фильтруете даты по алиасу [o], хотя джойн с этим уже справился.
        -- как уже было откоменчено выше, поля от алиаса [o] могут содержать в себе значения NULL.
        -- фильтр типа NULL >= '20121001' AND NULL <= '20121019' никогда не вернет истинного значения
        -- и строки с NULL'ами через такой фильтр не проходят.
        -- фактически этот фильтр делает из вашего left-join'а обычный inner-join, только очень извращенный.
        -- Вместо Вашего фильтра впишите мой:
        o.IdCust is null
GROUP BY p.IdPeriod
          ,p.IdCust
          ,p.PeriodFrom
          ,p.PeriodTo
19 окт 12, 16:35    [13347948]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
Glory
Member

Откуда:
Сообщений: 104751
mottura
Kopilogus
mottura,

Сколько записей выдает запрос:

SELECT p.IdPeriod
	,p.IdCust
	,DateDiff(Day,Min(o.DateOrder),Max(o.DateOrder)) Days
FROM PointPeriod p LEFT JOIN [Order] o 
	ON o.IdCust = p.IdCust AND o.DateOrder >= p.PeriodFrom AND o.DateOrder <= p.PeriodTo



Если добавить GROUP BY, то 60

У сколько из них o.IdCust равно null ?
19 окт 12, 16:39    [13347973]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

Откуда:
Сообщений: 55
Glory
mottura
пропущено...


Если добавить GROUP BY, то 60

У сколько из них o.IdCust равно null ?


o.IdCust = null (25 записей)
19 окт 12, 17:10    [13348123]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
mottura
Member

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

Да, я понял эту ошибку. Не увидел это в большом запросе.

Однако, используя

WHERE
        o.IdCust is null


получаем ноль записей.
19 окт 12, 18:50    [13348518]     Ответить | Цитировать Сообщить модератору
 Re: left join + where не работает  [new]
Ennor Tiegael
Member

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

В исходном запросе проблема, как и говорили, в упрощении. У вас отсутствует какое-либо условие по таблице PointPeriod, т.е. тянется вся история. В результате ваш запрос возвращает не "клиентов, которые в определенные периоды не заказывали", как вы хотели, а "клиентов, которые не заказывали никогда". По всей видимости, таковых не имеется.
19 окт 12, 21:50    [13349080]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить