SQL Server query to further summarize grouped data - sql

Assume a table named transactions with two columns: invoiceNumber and itemNumber. Multiple quantities of an item on a single invoice are reflected by multiple records in the table. (I know this isn't an appropriate design, but I'm simplifying a more complex structure to get at the root question.)
I can determine the average number of unique items for each invoice with a query like:
SELECT invoiceNumber, COUNT(DISTINCT itemNumber)
FROM transactions
GROUP BY invoiceNumber
This query effectively ignores the quantity of an item, counting each one only once per invoice and shows the result for each invoice.
Instead of all this detailed information, however, all I really want is to determine the average number of unique items across all invoices. That is, I just want to summarize the per-invoice information. How do I do that?

You can aggregate the result you've already figured out how to obtain.
WITH DistinctCounts AS (
SELECT invoiceNumber, COUNT(DISTINCT itemNumber) AS distinctItems
FROM transactions
GROUP BY invoiceNumber
)
SELECT AVG(distinctItems)
FROM DistinctCounts

Select avg(numberininvoice)
From
(
Select invoicenumber, count(itemnumber) as numberininvoie
From
(Select distinct invoicenumber, itemnumber
From transactions) a
Group by invoicenumber
) b

Related

Combining two queries using JOIN, GROUP BY and SUM?

I am stuck trying to write the correct query for this problem. So I have 2 tables orders and products where orders.user_id=products.buyer_id
I want to query from both tables and find out how much each person owes for their purchase, how much they actually paid, and finally the difference between the two (owes-paid).
The individual queries that work are
SELECT buyer_id, SUM(price) AS owes FROM products GROUP BY buyer_id ORDER BY buyer_id ASC;
and
SELECT user_id, SUM(amount_paid) AS paid FROM orders GROUP BY user_id ORDER BY user_id ASC;
I am able to do the right query but only on each table individually. However, when trying to combine both queries (Outer Join?), I get bad results.
Any help/guidance is appreciated.
I would suggest a sub query where you take the union of both, and dedicate a column to the paid amount and another to the due amount. Then apply the aggregation on that sub query:
SELECT user_id,
SUM(amount_due) AS owes,
SUM(amount_paid) AS paid,
SUM(amount_due) - SUM(amount_paid) AS diff
FROM (
SELECT user_id, amount_paid, 0 amount_due
FROM orders
UNION ALL
SELECT buyer_id, 0, price
FROM products
) AS transactions
GROUP BY user_id
ORDER BY user_id ASC;

Query for total number of orders with the same ID

Apologies if this is simple but I have just started learning SQL. In my Access database, I have a table that displays a list of orders:
I can filter the table down to just display the OrderID next to the Quantity of items like this:
SELECT OrderID, Quantity FROM OrderItems;
However in the table there are multiple OrderID's that are the same. How do I tell the database to total up the quantity of orders that relate to each OrderID?
Is is almost how you say it. You have to group the records by id and sum up the quantities. With SQL you do the following
SELECT
OrderID, <-- you get the OrderID that is grouped
SUM(Quantity) <-- you sum the quantities
FROM
OrderItems
GROUP BY
OrderId <-- you group the records by OrderId

SQL, DISTINCT product_id, orderQuantity

Here is the given question:
Show me a list of the product codes along with the number of times that each code has been ordered (note, order quantity does affect the number of total times ordered); only include product codes that have been ordered at least once?
I have tried the following
SELECT DISTINCT productId, orderQuantity
FROM Order
WHERE (orderQuantity > 0);
The table comes up with duplicate product ids. How do I get a table of distinct product ids with the SUM of their order quantities?
I think this is what you're looking for:
SELECT productID, SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
GROUP BY productID
You have to use an aggregate function, in this case SUM(), to have the sum of your quantities and you want the sums to be grouped by each product, in your case productID.
To understand how this works, just try removing the GROUP BY statement and the productID from the SELECT statement and the query will return the SUM of all quantities.
SELECT SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
Then, if you add just the GROUP BY productID you will get the sum of quantities ordered for each product.
SELECT SUM(orderQuantity)
FROM Order
WHERE orderQuantity > 0
GROUP BY productID
Then just add the productID back in the SELECT statement to understand the information displayed.

How can I rewrite this query without sub-queries?

So what I want to do:
I have a table that has some prices of some items of a store, what I want to do is to find the average price of all the items sold from that store, AND the sum of all similar items sold in store.
My columns are:
item_no
branch
totalamount
What is really important is that I have to avoid sub-queries so I couldn't do something like:
SELECT DISTINCT branch AS postcode, item_no, avg_price
FROM Prices
NATURAL JOIN (SELECT branch, AVG(totalamount) avg_price FROM Prices GROUP BY branch) av
WHERE sum > avg_price ORDER BY turnover DESC , branch;
Which does exactly what I want to do, nevertheless I have to do it without sub-queries.
edit 1 QUESTION:
IS THERE A DIFFERENCE between derived and temporary tables? so for the assignment , i am not allowed to use subqueries, OR temporary tables, so does my answer have any of those 2?
You can specify multiple aggregate statements on the same or different columns within the same SELECT statement. To see exactly what I mean have a look in books online.
http://msdn.microsoft.com/en-us/library/ms177677.aspx
here how you can do it,
SELECT branch AS postcode,
item_no,
AVG(totalamount) avg_price ,
SUM(totalamount) sum
FROM prices
WHERE SUM(totalamount) > avg_turnover
ORDER BY avg_turnover DESC ,
eatit_Order.branch
GROUP BY branch,
item_no;

How to get the products that all Warehouse exist?

I have a question as the title,I wanna get the products which appeared in every Warehouse,
I have no idea when i thought long time,i found i am so beetleheaded,
Thare are three tables in my sql server database:
Product
(
productID,
name,model,
size,
color
)
Warehouse
(
warehouseID,
name,
address
)
Inventory
(
warehouseID,
productID,
quantity
)
i hope someone help me to have a look and can write the sql that get the result
Thank you.
Use a GROUP BY to count the number of warehouses each product is in. Accept those rows for which this count is equal to the total number of warehouses.
SELECT productID
FROM Inventory
WHERE quantity > 0
GROUP BY productID
HAVING COUNT(*) = (SELECT COUNT(*) FROM Warehouse)
This assumes that (productID, warehouseID) is unique in the inventory table. If it is not then use COUNT(DISTINCT warehouseID) instead of COUNT(*).