How can I rewrite this query without sub-queries? - sql

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;

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;

How to use SUM and MAX on the same column?

So I'm having an SQL table where I will need find out the product that has been purchased the most meaning that I need to do a SUM and a group by on all the quantity of the products:
SELECT PRODUCT_ID, SUM(QUANTITY) FROM PURCHASE GROUP BY PRODUCT_ID
However when I try to find the product with the maximum amount of purchases it gives me an error:
SELECT MAX(QUANTITY) FROM(SELECT PRODUCT_ID, SUM(QUANTITY) FROM PURCHASE GROUP BY PRODUCT_ID)
Any ideas?
Just order by and keep the top record only:
SELECT PRODUCT_ID, SUM(QUANTITY) SUM_QUANTITY
FROM PURCHASE
GROUP BY PRODUCT_ID
ORDER BY SUM_QUANTITY DESC
LIMIT 1
The actual syntax might vary accross RDBMS. The above would work in MySQL and Postgres.
In SQL Server, you would use SELECT TOP (1) ... ORDER BY SUM_QUANTITY DESC.
In Oracle >= 12c, you would use SELECT ... ORDER BY SUM_QUANTITY DESC FETCH FIRST ROW ONLY.
You also have to consider the possibilty of ties in the first position, for which there are different strategies depending on your requirement and RDBMS.

I can't get max and min from my table

How come this query returns an error?
select CUSTOMER, TOTAL_VALUE
from CUSTOMER, SALES
where TOTAL_VALUE in (select max(TOTAL_VALUE), min(TOTAL_VALUE)
from SALES)
When I just do max(TOTAL_VALUE) or min(TOTAL_VALUE) alone it works perfectly. But I need to get the min number in TOTAL_VALUE and max number in TOTAL_VALUE. Can anyone help me figure out why this query won't work for me? I would like to keep the structure that i have (using the in operator and nested subquery)
It returns an error because the subquery is returning two values, not one. Here is one fix:
select CUSTOMER, TOTAL_VALUE
from CUSTOMER cross join
SALES join
(select max(TOTAL_VALUE) as maxt, min(TOTAL_VALUE) as mint
from sales
) sm
where s.total_value in (sm.maxt, sm.mint);
That said, the query makes no sense. There you are going to get a list of every customer along with the value of the overall minimum and maximum sales.
This does answer your question. If you have another question, then provide sample data, desired results, in another question.
Try this (Joining SALES and CUSTOMER tables):
select C.CUSTOMER, MIN(TOTAL_VALUE), MAX(TOTAL_VALUE)
from SALES S
join CUSTOMER C on S.Customer_ID=C.Customer_ID
group by C.CUSTOMER
order by C.CUSTOMER

SQL Server query to further summarize grouped data

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

How to obtain the top N max values of a total of products in a facts table

I have a typical star schema to emulate a real, but simple, DW. My fact tables is SALES and it has, besides other products, some attributes like amount_sold, quantity_sold (per product), unit price, etc.
Now I need to introduce some data in Weka to do a Data Mining Study in which I want to characterize the people that buy the top 3 products. So, I need, perhaps a aux table that has all the distinct products in sales and the total_quantity sold for each one of them.
AUX_TOTAL_PROD_SOLD would be something like this:
Collumn_1= prod_id
Collumn_2= total_sold
So, for this purpose, I need:
1- a PL/SQL procedure to fill my aux_Table
2- obtain the 3(or another number) most sold products
I just need to find them and then I can relate each prod_id with the client who bought it.
Do you think it's a complicated way to do this or do you think or have a better idea?
I'm testing it, but if you can I would appreciate some code/pseudo-code.
Thank you in advance
That's how I was able to achieve this:
SELECT * from
(SELECT prod_ID, SUM(s_quantity_sold) as TOTAL_SOLD
FROM SALES
GROUP BY prod_ID
ORDER BY SUM(s_quantity_sold) DESC )
where ROWNUM <=3
it works like a charm :)
SELECT TOP 3 Product_ID, SUM(quantity_sold) AS total_sold
FROM [SALES]
GROUP BY Product_ID
ORDER BY SUM(quantity_sold) DESC
or for SQL Server
DECLARE #n int
SET #n = 3
SELECT TOP (#n) Product_ID, SUM(quantity_sold) AS total_sold
FROM [SALES]
GROUP BY Product_ID
ORDER BY SUM(quantity_sold) DESC