Достаточно базовый c запрос (может быть, нужен подзапрос и / или внешнее соединение)? - PullRequest
1 голос
/ 21 февраля 2020

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

У меня есть 2 таблицы:

- Orders
(pk)orderID
customername
orderDate
- OrderDetails
(pk)detailsID
orderID
productName

Таким образом, при размещении нового заказа в Заказы добавляется одна строка с информацией о клиенте, а в таблице orderDetails добавляется строка для каждого заказанного продукта.

Итак, представьте эти 2 макета:

ORDERS
orderID     customerName    orderDate
1           John Smith       2/21/2020
2           Bill Adams       2/21/2020
3           Susan Conrad     2/21/2020
4           Amy Fetcher      2/21/2020
ORDERDETAILS
detailsID  orderID  productName
1             1      pillow
2             1      mattress
3             2      pillow
4             3      sheets
5             3      headboard
6             3      mattress
7             4      pillow
8             4      framed art
9             4      decals
10            4      plant stand

В моем запросе я хочу выбрать все из заказов, где дата = сегодня. Я присоединяюсь к таблице ORDERDETAILS, потому что хочу знать, когда я продал подушку в своих результатах.

Я хочу, чтобы в результатах отображалась только 1 строка для каждого заказа, поэтому в orderID 1, например, они заказали подушку и матрас. В результатах в productName для этой строки я хочу, чтобы она отображала подушку.

Если кто-то не заказывал подушку, мне все еще нужна строка, чтобы показать ее заказ сегодня, а в productName меня не волнует, что это показывает, если это не подушка. На нем может не отображаться ничего или одно из названий продуктов, которые они заказали.

Я знаю, что это не работает:

SELECT ORDERS.*, ORDERDETAILS.*
FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.orderID = ORDERDETAILS.orderID
WHERE productName = "pillow"

Я не уверен, нужны ли мне подзапросы или какой-либо внешний оставил, может быть, оба?

Любая помощь очень ценится, спасибо!

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

Поскольку вас интересуют только некоторые детали заказа, но все заголовки, вам нужен LEFT JOIN. А поскольку вы хотите фильтровать результаты только по ORDERDETAILS, вам понадобятся критерии фильтрации в JOIN, а не в предложении WHERE, которое также применяется к таблице ORDERS.

SELECT ORDERS.*, ORDERDETAILS.*
FROM 
  ORDERS 
LEFT JOIN ORDERDETAILS 
  ON ORDERS.orderID = ORDERDETAILS.orderID
  AND productName = "pillow"

Это должно помочь вам в этом. Если существует возможность более чем одной подробной записи для каждого заказа, которая включает pillow, то вы захотите использовать подзапрос к таблице подробностей, чтобы убрать его дальше, чтобы получить только интересующую вас информацию. в этот момент я бы переместил фильтр в подзапрос.

0 голосов
/ 21 февраля 2020

Вы можете сделать это следующим образом

select detailsID, a.orderID, productName, customerName, orderDate from 
(
    select detailsID, orderID, productName from ORDERDETAILS where productName = 'pillow'
    union 
    select detailsID, orderID, productName from
    (
    select detailsID, orderID, productName, rank()over(partition by orderID order by detailsID) as _Rank from ORDERDETAILS  
    )a where _Rank = 1
    and orderID not in (select orderID from ORDERDETAILS where productName = 'pillow')
) a
inner join Orders b on a.orderID = b.orderID

Вывод:

detailsID   orderID productName customerName    orderDate
1   1   pillow  John Smith  2/21/2020
3   2   pillow  Bill Adams  2/21/2020
4   3   sheets  Susan Conrad    2/21/2020
7   4   pillow  Amy Fetcher 2/21/2020
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...