SQL Get all orders which contain exclusively one kind of item
In this Database I want to count the number of orders that contain only products of a certain category.
I know how to count all orders that also contain items of a certain category, i.e. category 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";
I am having trouble finding an elegant way to get all orders that contain only category 1 items. I tried selecting all OrderIDs and grouping them by 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;
But I have no idea how to count all OrderIDs that contain category 1 items exclusively. Is my approach right? Or is there a better way to do it (Which I am sure there is)
mysql sql database join
add a comment |
In this Database I want to count the number of orders that contain only products of a certain category.
I know how to count all orders that also contain items of a certain category, i.e. category 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";
I am having trouble finding an elegant way to get all orders that contain only category 1 items. I tried selecting all OrderIDs and grouping them by 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;
But I have no idea how to count all OrderIDs that contain category 1 items exclusively. Is my approach right? Or is there a better way to do it (Which I am sure there is)
mysql sql database join
1
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14
add a comment |
In this Database I want to count the number of orders that contain only products of a certain category.
I know how to count all orders that also contain items of a certain category, i.e. category 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";
I am having trouble finding an elegant way to get all orders that contain only category 1 items. I tried selecting all OrderIDs and grouping them by 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;
But I have no idea how to count all OrderIDs that contain category 1 items exclusively. Is my approach right? Or is there a better way to do it (Which I am sure there is)
mysql sql database join
In this Database I want to count the number of orders that contain only products of a certain category.
I know how to count all orders that also contain items of a certain category, i.e. category 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";
I am having trouble finding an elegant way to get all orders that contain only category 1 items. I tried selecting all OrderIDs and grouping them by 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;
But I have no idea how to count all OrderIDs that contain category 1 items exclusively. Is my approach right? Or is there a better way to do it (Which I am sure there is)
mysql sql database join
mysql sql database join
asked Nov 22 '18 at 12:12
ksbawpnksbawpn
519
519
1
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14
add a comment |
1
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14
1
1
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14
add a comment |
2 Answers
2
active
oldest
votes
You can do filtering using HAVING
clause. We basically Count the order details rows where category is 1 for an order. It should be equal to the total count of rows for that order. This would ensure that all the categories in an order is 1 only.
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(*)
It is advisable to use Aliasing in case of multi-table queries for Code clarity and readability
add a comment |
You can use group by
and having
. . . but you need two levels. To get the orders that are all in one (or a set of categories) by doing:
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(*);
The count needs a subquery:
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;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53430760%2fsql-get-all-orders-which-contain-exclusively-one-kind-of-item%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can do filtering using HAVING
clause. We basically Count the order details rows where category is 1 for an order. It should be equal to the total count of rows for that order. This would ensure that all the categories in an order is 1 only.
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(*)
It is advisable to use Aliasing in case of multi-table queries for Code clarity and readability
add a comment |
You can do filtering using HAVING
clause. We basically Count the order details rows where category is 1 for an order. It should be equal to the total count of rows for that order. This would ensure that all the categories in an order is 1 only.
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(*)
It is advisable to use Aliasing in case of multi-table queries for Code clarity and readability
add a comment |
You can do filtering using HAVING
clause. We basically Count the order details rows where category is 1 for an order. It should be equal to the total count of rows for that order. This would ensure that all the categories in an order is 1 only.
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(*)
It is advisable to use Aliasing in case of multi-table queries for Code clarity and readability
You can do filtering using HAVING
clause. We basically Count the order details rows where category is 1 for an order. It should be equal to the total count of rows for that order. This would ensure that all the categories in an order is 1 only.
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(*)
It is advisable to use Aliasing in case of multi-table queries for Code clarity and readability
answered Nov 22 '18 at 12:14
Madhur BhaiyaMadhur Bhaiya
19.5k62236
19.5k62236
add a comment |
add a comment |
You can use group by
and having
. . . but you need two levels. To get the orders that are all in one (or a set of categories) by doing:
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(*);
The count needs a subquery:
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;
add a comment |
You can use group by
and having
. . . but you need two levels. To get the orders that are all in one (or a set of categories) by doing:
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(*);
The count needs a subquery:
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;
add a comment |
You can use group by
and having
. . . but you need two levels. To get the orders that are all in one (or a set of categories) by doing:
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(*);
The count needs a subquery:
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;
You can use group by
and having
. . . but you need two levels. To get the orders that are all in one (or a set of categories) by doing:
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(*);
The count needs a subquery:
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;
answered Nov 22 '18 at 12:15
Gordon LinoffGordon Linoff
765k35296400
765k35296400
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53430760%2fsql-get-all-orders-which-contain-exclusively-one-kind-of-item%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Such orders "do not contain" products from categories "different to 1".
– GSerg
Nov 22 '18 at 12:14