SQL Получить все заказы, которые содержат исключительно один вид товара - PullRequest
0 голосов
/ 22 ноября 2018

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

Я знаю, как подсчитать все заказы, которые также содержат товары определенной категории, то есть категории 1:

SELECT Count(DISTINCT orderdetails.orderid) AS "AllCat1" 
FROM   orderdetails 
       INNER JOIN orders 
               ON orderdetails.orderid = orders.orderid 
                  AND orderdetails.productid IN (SELECT DISTINCT productid 
                                                 FROM   products 
                                                 WHERE  categoryid = 1) 
WHERE  orderdate BETWEEN "1996-12-01" AND "1996-12-31"; 

У меня не получается найти элегантный способ получить все заказы, содержащие толькопредметы категории 1.Я попытался выбрать все OrderID и сгруппировать их по OrderID AND CategoryID:

SELECT * 
FROM   orderdetails 
       INNER JOIN orders 
               ON orderdetails.orderid = orders.orderid 
                  AND orderdate BETWEEN "1996-12-01" AND "1996-12-31" 
       INNER JOIN products 
               ON orderdetails.productid = products.productid 
GROUP  BY orderdetails.orderid, 
          categoryid;

Но я не знаю, как подсчитать все OrderID, которые содержат исключительно элементы категории 1.Правильный ли мой подход?Или есть лучший способ сделать это (который, я уверен, есть)

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Вы можете использовать group by и having.,,но вам нужно два уровня.Чтобы получить все заказы в одном (или наборе категорий), выполните следующие действия:

SELECT o.orderId 
FROM orders o JOIN
     orderdetails od
     ON od.orderid = o.orderid JOIN
     products p
     ON p.productid = od.productid
WHERE o.orderdate BETWEEN '1996-12-01' AND '1996-12-31'
GROUP BY o.orderId
HAVING SUM(CASE WHEN p.categoryid IN (1) THEN 1 ELSE 0 END) = COUNT(*);

Для подсчета требуется подзапрос:

SELECT COUNT(*)
FROM (SELECT o.orderId 
      FROM orders o JOIN
           orderdetails od
           ON od.orderid = o.orderid JOIN
           products p
           ON p.productid = od.productid
      WHERE o.orderdate BETWEEN '1996-12-01' AND '1996-12-31'
      GROUP BY o.orderId
      HAVING SUM(CASE WHEN p.categoryid IN (1) THEN 1 ELSE 0 END) = COUNT(*)
     ) o;
0 голосов
/ 22 ноября 2018

Вы можете выполнить фильтрацию, используя предложение HAVING.Мы в основном считаем строки деталей заказа, где категория 1 для заказа.Он должен быть равен общему количеству строк для этого заказа.Это обеспечит, чтобы все категории в заказе были только 1.

SELECT od.orderid 
FROM   orderdetails AS od 
       INNER JOIN orders AS o
               ON od.orderid = o.orderid 
                  AND o.orderdate BETWEEN "1996-12-01" AND "1996-12-31" 
       INNER JOIN products AS p
               ON od.productid = p.productid 
GROUP  BY od.orderid 
HAVING COUNT(CASE WHEN p.categoryid = 1 THEN 1 END) = COUNT(*)

Рекомендуется использовать Псевдоним в случае многостоловых запросов для ясности и читаемости кода

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