Display 2 columns from one table having max count in column 3 and display computed sum of values from another table - sql

I've a customer table and purchases table,
need to show cname, cid with max(customer_visits) from customer table
and sum of total_purchases by customer in purchases table.
I'm doing something like this
select p.cid, c.cname, sum(p.total_price)
from customers c where exists
(select max(visits_made) from customers having visits_made=max(visits_made)
and cid=p.cid)
inner join purchases p on p.cid=c.cid
group by p.cid,c.cname
and
select p.cid, c.cname, sum(p.total_price)
(select max(visits_made) from customers c where c.cid=p.cid)
from purchases p
inner join customers c on c.cid=p.cid
group by p.cid,c.cname
What's going wrong with these queries?
Found the solution, had to include where clause after inner join :D

I think this is just an aggregation query:
select p.cid, c.cname, sum(p.total_price) as total_price,
max(visits_made) as visits_made
from purchases p inner join
customers c
on c.cid = p.cid
group by p.cid, c.cname;

Related

What is the valid SQL query for the following JOIN problem

I have the following tables
Customer (CID, name, address)
Orders (CID, BID, onDate, quantity)
Device (DID, title, IMEI, price, MID)
Manufacturer (MID, name, address)
What SQL statement would allow me to retrieve the ID's and names of all
the customers who have spent atleast X amount (lets say 350 for example)
on devices made my the manufacturer "Sony". The list should include the total amount of money spent by each customer on those devices.
I assume that the table Orders contains a column DID (BID is a typo, right?) that relates it to the table device.
Join the tables, group by customer to aggregate and set the condition in the HAVING clause:
select c.CID, c.name,
sum(o.quantity * d.price) total_amount
from customer c
inner join orders o on o.CID = c.CID
inner join device d on d.DID = o.DID
inner join manufacturer m on m.MID = d.MID
where m.name = 'Sony'
group by c.CID, c.name
having sum(o.quantity * d.price) >= 350

How to make it in one query

I have the following relational table schema
Customer(customer_id, customer_name, customer_city)
Branch(branch_id, branch_name, branch_city)
Account(account_id, balance, customer_id, branch_id)
Question name every customer who has accounts in branches at least two different cities.
It is working for me the next query but only if I create a view first. Is there any other option to do it together?
My solution which works:
Create view Cust as select c.Customer_Name, c.customer_ID, b.branch_name, b.branch_city from Customer as c inner Join Account as a on c.customer_ID=a.customer_ID join Branch as b on b.branch_id=a.branch_id
SELECT * FROM Cust as c inner join Cust as c1 on c.CustomerID=c1.CustomerID and c.branch_city <> c1.branch_city
Here is one option using exists with an aggregate query
select c.*
from customer c
where exists (
select 1
from account a
inner join branch b on b.branch_id = a.branch_id
where a.customer_id = c.customer_id
group by c.customer_id
having min(b.branch_city) <> max(b.branch_city)
)

need help to write a query about this db

I have this DB and I need help with this query
Find the customer ID, first name, last name and the movie Name
of the customer that bought the most ticket in that day
I found the customer who bought the highest number of tickets in that day, now I need to find the movies that he bought tickets for
SELECT c.*, COUNT(*) 'bought'
FROM customer c JOIN ticket t ON c.customerId=t.customerId
GROUP BY c.customerId
HAVING bought=(SELECT MAX(T1.CNT)
FROM (SELECT COUNT(*) AS CNT
FROM customer c JOIN ticket t ON c.customerId=t.customerId
GROUP BY c.customerId) AS T1)
So without building the database and populating it with dummy data I can't test this, but I think I found a solution for you.
SELECT C.CUSTOMERID, C.FIRSTNAME, C.LASTNAME, M.TITLE
FROM CUSTOMER C JOIN TICKET T ON C.CUSTOMERID = T.CUSTOMERID JOIN SHOWS S ON T.SHOWNUMBER = S.SHOWNUMBER JOIN MOVIE M ON M.MOVIEID = S.MOVIEID
WHERE C.CUSTOMERID IN(
SELECT C1.CUSTOMERID FROM(
SELECT CUST.CUSTOMERID, COUNT(*) 'BOUGHT'
FROM CUSTOMER CUST JOIN TICKET TICK ON CUST.CUSTOMERID = TICK.CUSTOMERID
GROUP BY CUST.CUSTOMERID
HAVING BOUGHT = (SELECT MAX(T1.CNT) FROM (SELECT COUNT(*) AS CNT FROM CUSTOMER CUSTO JOIN TICKET TICKE ON CUSTO.CUSTOMERID = TICKE.CUSTOMERID GROUP BY CUSTO.CUSTOMERID)AS T1) AS C1);

SQL Subtract two columns on different tables

I have two tables, Customer, and Invoices,I have to list all the customers with their remaining credit. I'm trying to subtract the sum of the Invoice Amount column from the CreditLimit column to give me the remaining credit?
This is my query so far
DECLARE #CreditRemaining INT
SELECT
#CreditRemaining = (c.CreditLimit - SUM(i.Amount))
FROM
Customer c
INNER JOIN
Invoices i on
c.ID = i.customerId
Use a derived table for the invoice amount SUM(), then JOIN back to Customer:
DECLARE #CreditRemaining INT
SELECT #CreditRemaining = (c.CreditLimit - TotalSpent)
FROM Customer c
INNER JOIN (SELECT SUM(Amount) TotalSpent, CustomerID
FROM Invoices
GROUP BY CustomerID) i ON i.CustomerID = c.ID
As others mentioned, this is assuming you are limiting your selection to one customer.
For all customers, just use a select:
SELECT C.Name, (c.CreditLimit - TotalSpent) CreditRemaining
FROM Customer c
INNER JOIN (SELECT SUM(Amount) TotalSpent, CustomerID
FROM Invoices
GROUP BY CustomerID) i ON i.CustomerID = c.ID
GROUP BY C.Name

Fetch data from more than one tables using Group By

I am using three tables in a PostgreSql database as:
Customer(Id, Name, City),
Product(Id, Name, Price),
Orders(Customer_Id, Product_Id, Date)
and I want to execute a query to get from them "the customers that have have ordered at least two different products alnong with the products". The query I write is:
select c.*, p.*
from customer c
join orders o on o.customer_id = c.id
join product p on p.id = o.product_id
group by (c.id)
having count(distinct o.product_id)>=2
It throws the error:
"column "p.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select c.*, p.*".
However if I remove the the p.* from select statement (assuming that I one does not want the products, only the customers), it runs fine. How can I get the products as well?
Update: Having ordered two or more products, a customer must appear on the output as many times as its product he has ordered. I want as output a table with 5 columns:
Cust ID | Cust Name | Cust City | Prod ID | Prod Name | Prod Price
Is it possible in SQL given that group by should be used? Shoul it be used on more than one columns on different tables?
Try this out :
SELECT distinct c.* ,p.*
FROM Customer c
JOIN
(SELECT o.customer_id cid
FROM Product P
JOIN Orders o
ON p.id= o.product_id
GROUP BY o.customer_id
HAVING COUNT(distinct o.product_id)>=2) cp
ON c.id =cp.cid
JOIN Orders o
on c.id=o.customer_id
JOIN Product p
ON o.product_id =p.id
I hope it solves your problem.
I think you can use following query for this question -
SELECT C1.*, p1.*
FROM Customer C1
JOIN Orders O1 ON O1.Customer_Id = C1.Id
JOIN Product P1 ON P1.Id = O1.Product_Id
WHERE C1.Id IN (SELECT c.Id
FROM Customer c
JOIN Orders o ON o.Customer_Id = c.Id
GROUP BY (c.Id)
HAVING COUNT(DISTINCT o.Product_Id) >= 2)