Условия Sql Not IN и Not Exists не работают с условием Where - PullRequest
0 голосов
/ 28 сентября 2019

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

Когда я по отдельности выполняю NOT IN и NOT EXIST Запросы, я получаю в результате элементы, которых нет в таблице ItemsSold.Что здесь не так?

Полный запрос с NOT EXISTS

select MAx(ITM.Name) as Name,Max(ITM.ItemID) as ID,Max(ItemsSold.UpdatedDate) as LastSaleDate from Items ITM
Inner join ItemsSold on ItemsSold.ItemID = ITM.ItemID
where convert(varchar,ItemsSold.UpdatedDate,111) < '2019/04/01'
or  NOT EXISTS (select ItemsSold.ItemID from ItemsSold where ItemsSold.ItemID=ITM.ItemID) 
Group by ITM.ItemID order by ITM.ItemID;  

Полный запрос с NOT IN

select MAx(ITM.Name) as Name,Max(ITM.ItemID) as ID,Max(ItemsSold.UpdatedDate) as LastSaleDate from Items ITM
Inner join ItemsSold on ItemsSold.ItemID = ITM.ItemID
where convert(varchar,ItemsSold.UpdatedDate,111) < '2019/04/01'
or ITM.ItemID NOT IN (select ItemsSold.ItemID from ItemsSold) 
Group by ITM.ItemID order by ITM.ItemID  

NOTIN отдельно

select Items.Name,Items.ItemID from Items where Items.ItemID NOT IN (select ItemsSold.ItemID from ItemsSold) order by ItemID  

Выполнение NOT IN и NOT EXISTS Query отдельно возвращает действительные правильные данные, но при полном запросе это не так.

Ответы [ 2 ]

2 голосов
/ 28 сентября 2019

Без примерных данных или ожидаемых результатов, однако, это предположение, основанное исключительно на вашем существующем SQL и вашем комментариипродано. " это может быть то, что вам нужно:

SELECT I.ItemID
FROM Items I
     LEFT JOIN ItemsSold ItS ON I.ItemID = ItS.ItemID
GROUP BY I.ItemID
HAVING MAX(ItS.UpdatedDate) < '20190401' --Proper date logic, got rid of CONVERT
    OR MAX(ItS.ItemID) IS NULL;

Возможно, вы захотите MIN(ItS.UpdatedDate), в зависимости от того, хотите ли вы, чтобы вещи, которые были только проданы ранее2019-04-01 или если вы хотите, чтобы товары, которые были хотя бы сначала проданы до 2019-04-01 (невозможно узнать из-за отсутствия описания).

Если нет, я ссылаюсь на свой предыдущий комментарий «нам нужны образцы данных, которые повторяют« проблему »и ожидаемые результаты». .

1 голос
/ 28 сентября 2019

Вы, похоже, хотите, чтобы товары, которые были только проданы до определенной даты или никогда не продавались.То есть никакие элементы не были проданы позже:

Использовать not exists:

select i.*
from items i
where not exists (select 1
                  from itemssold its
                  where its.ItemId = i.ItemId and
                        its.UpdatedDate >= '2019-04-01'
                 );

Вам нужны соответствующие индексы независимо от того, как вы сформулировали запрос, если производительность является фактором.Для этого индекс будет на itemssold(ItemId, UpdatedDate).Это должно быть намного быстрее, чем форма агрегации запроса.

Если вопрос больше в том, как он сформулирован: существует заказ до даты или нет заказов вообще, тогда вы бы использовали два сравнения:

select i.*
from items i
where exists (select 1
              from itemssold its
              where its.ItemId = i.ItemId and
                    its.UpdatedDate < '2019-04-01'
             ) or
      not exists (select 1
                  from itemssold its
                  where its.ItemId = i.ItemId
                 );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...