I can't get max and min from my table - sql

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

Related

A simple subquery in SQL

I have a table ORDERS with columns NAME and AMOUNT.
I need to get a NAME and total AMOUNT of each product.
I have such a solution
select PRODUCT_NAME, SUM(AMOUNT) from ORDERS GROUP BY PRODUCT_NAME;
But I dont use any subqueries for achieving that. But the lesson that Im going through is about subqueries. May be Im wrong about this solution?
Its a simple aggregation query without a need of sub query like:
SELECT name, SUM(AMOUNT)
FROM Orders
GROUP BY name
This solution is perfectly fine:
selectname, sum(amount)
from Orders
group by name
But, if you must use subquery, use this:
select o2.name,
(select sum(amount)
from Orders o1
where o1.name = o2.name) as total
from
(select distinct name
from Orders) o2

Complex Aggregations in SQL

All I want to do is get a data set that shows me how many orders were placed and how many calls were made for each order. I also need the date of the calls and the date of the order, in the same table. The table is 10M+ rows, so aggregation of the result set is essential for analysis. The only analysis I want to do is the sum of calls/the total orders, and to be able to see how many support_tickets were generated from orders within an order range, up to a call_date. Very simple, but surprisingly complex to code up. Here is my attempt. I have also tried to change the below into a union, but still get wrong aggregate results.
-- The Query:-
SELECT
category_name
count(order_code)
order_date
sum(support_ticket_call)
call_date
FROM
(Select distinct name, order_code, order_date from table1) b
left join
(select count(call_ids), call_date FROM table2) b
on b.order_ID_code = a.order_id_code
group by category_name, order_date, call_date
Whenever there are no support_ticket_calls, the call_date is NULL, as you would expect. The count of orders is like 60,000 though, which is different from the usual 12 or so in the rest of the result set. I know something is wrong with this query, but It's driving me insane trying to solve it, literally all day so far.
It's a little difficult to answer this question without sample data and expected results, but the comment was getting too long.
You have several problems with your current query. First you need to join on the date fields by using on criteria. You also need to add group by to those queries that use aggregation. Finally, where does support_ticket_call come from? Can I presume it's the alias for the count(call_ids)?
Something like this should get you close:
SELECT
a.name as category_name,
count(a.order_code),
sum(b.support_ticket_call),
a.order_date as call_date
FROM
(Select distinct name, order_code, order_date
from table1) a
left join
(select count(call_ids) as support_ticket_call, call_date
from table2 group by call_date) b on a.order_date = b.call_date
group by a.name, a.order_date

PostgreSQL how to compare a column's numeric value against the SUM of another numeric value?

I am new to PostgreSQL and restored this Database in order to practice my Queries. It contains the following Tables:
What is the best query to find how many orders have an order_total that is less than the sum of their line_total(s)?
This is the query I have but I doubt that my number is accurate. I feel like I am doing something wrong:
select COUNT(order_total) from orders
join order_lines
on orders.id = order_lines.order_id
having count(order_total) < sum(line_total)
Am I querying correctly or not?
Thanks
Pill
perhaps something like this
select o.order_total,sum( l.line_total) as sum_line_total
from orders o join order_lines l on o.orders.id=l.order_id
group by o.order_total
having o.order_total < sum(l.line_total)
That answer gave more than one result. I experimented and came across the correct answer by using the following sub-query:
select count(*) from orders,
(Select order_id, sum(line_total) from order_lines group by order_id) a
where order_total < a.sum and order_id = orders.id;
Thanks though for the response
Pill

PostgreSQL: get the min of a column with it's associated city

I have been at this for the past two hours and have tried many different ways in regards to subquery and joins. Here's the exact question "Get the name and city of customers who live in the city where the least number of products are made"
Here is a snapshot of the database tables
I know how to get the min
select min(quantity)
from products
but this returns just the min without the city attached to it so I can't search for the city in the customers table.
I have also tried group by and found it gave me 3 min's (one for each group of cities) which i believe may help me
select city,min(quantity)
from products
group by city
Putting everything together I got something that looks like
SELECT
c.name,c.city
FROM
customers c
INNER JOIN
(
SELECT
city,
MIN(quantity) AS min_quantity
FROM
products
GROUP BY
city
) AS SQ ON
SQ.city = c.city
But this returns multiple customers, which isn't correct. I assume by looking at the database the city when the lowest number of products seems to be Newark and there are no customers who reside in Newark so I assume again this query would result in 0 hits.Thank you for your time.
Example
Here is an example "Get the pids of products ordered through any agent who makes at least one order for a customer in Kyoto"
and the answer I provided is
select pid
from orders
inner join agents
on orders.aid = agents.aid
inner join customers
on customers.cid = orders.cid
where customers.city = 'Kyoto'
In Postgresql you have sophisticated tools, viz., windowing and CTEs.
WITH
find_least_sumq AS
(SELECT city, RANK() OVER ( PARTITION BY city ORDER BY SUM(quantity) ) AS r
FROM products)
SELECT name, city
FROM customers NATURAL JOIN find_least_sumq /* ON city */
WHERE r=1; /* rank 1 is smallest summed quantity including ties */
In Drew's answer, you are zeronig in on the cities where the smallest number of any particular item is made. I interpret the question as wanting the sum of items made in that city.
I guess it be something around this idea:
select customers.name, city.city, city.min
from customers
join (
select city, sum (quantity) as min
from products
group by city
--filter by the cities where the total_quantity = min_quantity
having sum (quantity) = (
--get the minimum quantity
select min(quantity) from products
)
) city on customers.city = city.city
This can be made so much simpler. Just sort the output by the field you want to get the minimum of.
SELECT city, quantity FROM customers ORDER BY quantity LIMIT 1;
I have just figured out my own answer. I guess taking a break and coming back to it was all I needed. For future readers this answer will use a subquery to help you get the min of a column and compare a different column (of that same row) to a different tables column.
This example is getting the city where the least number of products are made (quantity column) in the products table and comparing that city to the cities to the city column in the customers table, then printing the names and the city of those customers. (to help clarify, use the link in the original question to look at the structure of the database I am talking about) First step is to sum all the products to their respective cities, and then take the min of that, and then find the customers in that city.Here was my solution
with citySum as(
select city,sum(quantity) as sum
from products
group by city)
select name,city
from customers
where city
in
(select city
from citySum
where sum =(
select min(sum)
from citySum))
Here is another solution I have found today that works as well using only Sub queries
select c.name,c.city
from customers c
where c.city
in
(select city
from
(select p.city,sum(p.quantity) as lowestSum
from products p
group by p.city) summedCityQuantities
order by lowestsum asc
limit 1)

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;