Left Join из трех столов - PullRequest
0 голосов
/ 03 мая 2020

Я беру базовый c курс по базе данных, и у нас возник вопрос, который я изо всех сил пытаюсь найти хорошее решение.

Мы должны запросить упрощенную базу данных SQLite NorthWind для продуктов, которые сделали не продавать в апреле 2014 года.

Мне нужно запросить три таблицы, чтобы получить это, таблицы Product, OrderItem и Order. OrderItem - это таблица с ProductId и OrderId. Таблица Order содержит OrderDate.

Предшествующая лекция посвящена различным объединениям, и я подозреваю, что эта частичная проблема связана с левыми объединениями, поскольку я хочу перечислить продукты без записей в таблице OrderItem после фильтрации Order by date.

Вот мой запрос:

SELECT COUNT(OI.Id) AS Amount, P.ProductName, O.OrderDate
  FROM Product P 
  LEFT JOIN OrderItem OI ON P.Id = OI.ProductId 
  LEFT JOIN [Order] O ON O.Id = OI.OrderId
  WHERE O.OrderDate LIKE("Apr%2014%")
  GROUP BY P.ProductName
  HAVING Amount = 0
  ORDER BY Amount;

Возвращает пустой набор результатов. Кто-нибудь может указать мне правильное направление, как решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

Нет необходимости в агрегации. Все, что вам нужно, это продукты, которые не соответствуют левым соединениям:

SELECT P.ProductName
FROM Product P 
LEFT JOIN OrderItem OI ON P.Id = OI.ProductId 
LEFT JOIN [Order] O ON O.Id = OI.OrderId AND O.OrderDate LIKE '%Apr%2014%'
WHERE O.Id IS NULL

Условие для даты помещено в предложение ON вместо предложения WHERE. Это будет работать, если формат ваших дат похож на %MMM%YYYY%, который не является допустимым форматом даты для SQLite.

0 голосов
/ 03 мая 2020

Вы можете сделать это с left join. Но исправьте сравнение дат, чтобы использовать ДАТЫ. И переместите условие в предложение ON:

SELECT P.*
FROM Product P LEFT JOIN
     OrderItem OI
     ON P.Id = OI.ProductId LEFT JOIN
     [Order] O
     ON O.Id = OI.OrderId AND
        O.OrderDate >= '2014-04-01' AND
        O.OrderDate < '2014-05-01'
WHERE O.Id IS NULL;

. Непонятно, почему у вас GROUP BY. Если вы хотите отдельные продукты, то GROUP BY не требуется.

0 голосов
/ 03 мая 2020

Я бы порекомендовал not exists для этого:

select p.*
from products p
where not exists (
    select 1 
    from orderItem oi 
    left join [order] o on o.id = oi.orderId
    where 
        oi.product = p.id
        and o.orderDate >= '2014-04-01'
        and o.orderDate <  '2014-05-01'
)

У меня нет базы данных SQLite Northwind под рукой, но я бы предположил, что даты хранятся в формате даты, таком как yyyy-mm-dd, отсюда и вышеприведенное выражение для фильтрации в апреле 2014 года. С другой стороны, если они действительно использовали какой-то пользовательский формат, вы можете придерживаться своего выражения like - остальная часть запроса остается прежней.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...