Reputation: 3579
I have an unnormalized table of customer orders. I want count how many products are sold and display it in table by type.
OnlineSalesKey SalesOrderNumber ProductKey
--------------------------------------------
1 20121018 778
2 20121018 774
3 20121018 665
4 20121019 772
5 20121019 778
9 20121019 434
10 20121019 956
11 20121020 772
12 20121020 965
15 20121020 665
16 20121020 778
17 20121021 665
My query:
SELECT
s.ProductKey, COUNT (*) As Purchased
FROM
Sales s
GROUP BY
s.ProductKey
Question #1.
That query does a job. But now I want display and take into account only those orders where more than one item is purchased. Not sure how do i do that in one query. Any ideas?
Question #2
Is it possible to normalize results and get back data separated by semi column?
20121018 | 778; 774; 665
Thanks!
Upvotes: 0
Views: 1002
Reputation: 107786
display and take into account only those orders...
SELECT s.SalesOrderNumber, COUNT (*) As Purchased
FROM Sales s
GROUP BY s.SalesOrderNumber
HAVING COUNT(*) > 1
So we group by the orders, apply the condition in HAVING, then display the SalesOrderNumber in the SELECT clause.
MySQL:
SELECT s.SalesOrderNumber, GROUP_CONCAT(DISTINCT ProductKey
ORDER BY ProductKey SEPARATOR '; ')
FROM Sales s
GROUP BY s.SalesOrderNumber
SQL Server: See this answer to a duplicate question. Basically, using FOR XML.
Upvotes: 2
Reputation: 51000
You don't say which SQL database you're using, and there will be different, more-or-less efficient answers for each database. (Sorry, just noticed MSSQL is in the question title.)
Here's a solution that will work in all or most databases:
SELECT s.ProductKey, COUNT (*) As Purchased
FROM Sales s
WHERE SalesOrderNum IN
(SELECT SalesOrderNum FROM Sales GROUP BY SalesOrderNum HAVING COUNT(*) > 1)
GROUP BY s.ProductKey
This is not the most efficient, but should work across the most products.
Also, please note that you're using the terms normalized and unnormalized in reverse. The table you have is normalized, the results you want are de-normalized.
There is no standard SQL statement to get the de-normalized results you want using SQL alone, but some databases (MySQL and SQLite) provide the group_concat function to do just this.
Upvotes: 4
Reputation: 55509
SELECT s.ProductKey, COUNT (*) As Purchased
FROM
Sales s
GROUP BY s.ProductKey
having count(*) > 1
EDIT -
Answer 1 - To display products for which orders had more than one product purchased -
SELECT s.ProductKey, COUNT (*) As Purchased
FROM Sales s
WHERE SalesOrderNum in
(
select SalesOrderNum from Sales
group by SalesOrderNum having count(*) > 1
)
GROUP BY s.ProductKey
Upvotes: 1
Reputation: 74078
1) Try this one:
SELECT s.ProductKey, COUNT (*) As Purchased
FROM
Sales s
GROUP BY s.ProductKey
HAVING COUNT(*) > 1
Upvotes: 1