SQLite Query testing for multiple row matches - sql

I am a bit stuck trying to query this:
Find all Customers that have ordered the same as Customer Number 250
Schema for database:
Customers(
customerNumber INTEGER, PRIMARY KEY
);
Orders(
orderNumber INTEGER, PRIMARY KEY
customerNumber INTEGER NOT NULL,
FOREIGN KEY (customerNumber) REFERENCES Customers
);
OrderDetails (
orderNumber INTEGER NOT NULL,
productCode TEXT NOT NULL,
PRIMARY KEY (orderNumber, productCode),
FOREIGN KEY (productCode) REFERENCES Products
);
I figured the query:
select DISTINCT customerNumber
FROM Orders Natural
JOIN OrderDetails
WHERE productCode NOT IN (
select productCode
FROM Orders NATURAL JOIN OrderDetails
WHERE customerNumber = 219
)
order by customerNumber;
would be correct but it returns nothing, so clearly I am misunderstanding something.

As you need all customer those are order all the product that 250 order or more than 250 but have same product , so tried with conditional aggregation
select customerNumber
FROM Orders o
JOIN OrderDetails od
on o.orderNumber =od.orderNumber
WHERE od.productCode IN (
select productCode
FROM Orders o
JOIN OrderDetails od
on o.orderNumber =od.orderNumber
WHERE customerNumber = 250
)
group by customerNumber
having count(distinct productCode )>=
(select count(distinct productCode )
FROM Orders o
JOIN OrderDetails od
on o.orderNumber =od.orderNumber
WHERE customerNumber = 250)

Related

How to use SUM and MAX in SQL

I want to give the name of the product that has been sold the most overall with its sales quantity. Total Quantity is the sum of products sold - that are the products whose order status (order_status) is Paid or Shipped.
I have the following tables:
CREATE TABLE products (
product_id SERIAL PRIMARY KEY,
product_name VARCHAR NOT NULL,
product_price numeric NOT NULL,
product_type product_types NOT NULL,
product_created_at TIMESTAMP NOT NULL DEFAULT NOW()
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
order_store_id INT NOT NULL REFERENCES stores,
order_user_id INT NOT NULL REFERENCES users,
order_status order_states NOT NULL,
order_created_at TIMESTAMP NOT NULL DEFAULT NOW()
CREATE TABLE order_items (
order_id INT references orders,
product_id INT references products,
quantity INT DEFAULT 1 CHECK ( quantity > 0 ),
PRIMARY KEY (order_id, product_id)
I have written the query:
SELECT products.product_name, maxam
FROM products, (SELECT SUM(quantity) AS total FROM order_items) AS foo
WHERE orders.order_id = order_items.order_id AND orders.order_status IN ('Paid', 'Shipped')
GROUP BY orders.order_status
HAVING maxam = MAX(total)
, but I think there are a lot of mistakes (working with sql for the first time)
try this
SELECT top 1 products.product_name, SUM(quantity) as QTY
FROM
orders inner join
order_items
on orders.order_id = order_items.order_id
order_items inner join
products
on order_items.product_id = products.product_id
WHERE orders.order_status IN ('Paid', 'Shipped')
GROUP BY products.product_name
order by qty desc
Working query:
SELECT products.product_name , SUM(quantity) AS QTY
FROM orders JOIN order_items ON orders.order_id = order_items.order_id JOIN products ON order_items.product_id = products.product_id
WHERE order_status IN ('Paid', 'Shipped')
GROUP BY products.product_name
ORDER BY QTY desc LIMIT 1;

Oracle query for customers who buy popular products

I have three tables: customer, order and line items. They are set up as follows:
CREATE TABLE cust_account(
cust_id DECIMAL(10) NOT NULL,
first VARCHAR(30),
last VARCHAR(30),
address VARCHAR(50),
PRIMARY KEY (cust_id));
CREATE TABLE orders(
order_num DECIMAL(10) NOT NULL,
cust_id DECIMAL(10) NOT NULL,
order_date DATE,
PRIMARY KEY (order_num));
CREATE TABLE line_it(
order_id DECIMAL(10) NOT NULL,
line_id DECIMAL(10) NOT NULL,
item_num DECIMAL(10) NOT NULL,
PRIMARY KEY (order_id, line_id),
FOREIGN KEY (item_id) REFERENCES products);
I need to write a query that selects customers, their names and addresses who have purchased items that have been bought by 3 or more people. I have the following query:
SELECT cust_account.cust_id, cust_account.first, cust_account.last, cust_account.address
FROM cust_account
INNER JOIN orders ON cust_account.cust_id = orders.cust_id
INNER JOIN line_it ON orders.order_id = line_it.order_id
GROUP BY cust_account.cust_id, cust_account.last
HAVING COUNT(line_it.item_num) = (
SELECT COUNT (DISTINCT order_num > 3)
FROM line_it
);
Do I even need to make it a subquery? I am a bit lost. Appreciate any help, thanks.
Start with "items bought by 3 or more people". You can get these by doing:
select li.item_id
from line_item li join
order_info oi
on li.order_id = oi.order_id
group by li.item_id
having count(distinct oi.customer_id) >= 3;
Now you want customers in this set. Hmmmm:
select distinct ca.*
from customer_account ca join
orderinfo oi
on ca.customer_id = oi.customer_id join
line_item li
on li.order_id = oi.order_id
where li.item_id in (select li.item_id
from line_item li join
order_info oi
on li.order_id = oi.order_id
group by li.item_id
having count(distinct oi.customer_id) >= 3
);
You can also express this with window functions:
select distinct ca.*
from (select ca.*, count(distinct customer_id) over (partition by li.item_id) as num_customers_on_item
from customer_account ca join
orderinfo oi
on ca.customer_id = oi.customer_id join
line_item li
on li.order_id = oi.order_id
) ca
where num_customers_on_item >= 3;
You can use the following query
SELECT distinct customer_account.* FROM line_item, order_info ,customer_account where item_id in (
--Selecting only item purchased 3 or more
SELECT item_id FROM line_item group by item_id having count(1) >=3
)
and line_item.order_id = order_info.order_id
and customer_account.customer_id = order_info.customer_id
;

SQL: How can I retrieve total amount from joined tables?

My tables
CREATE TABLE Customers (
id SERIAL PRIMARY KEY,
firstname VARCHAR(50),
lastname VARCHAR(50)
);
CREATE TABLE Payments (
id SERIAL PRIMARY KEY,
amount INT,
customer_id INT,
CONSTRAINT fk_CustomerPayment FOREIGN KEY (customer_id) REFERENCES Customers (id)
);
I want to get total payment amount for all customers. Here is my try:
SELECT SUM(p.amount)
FROM Customers c
JOIN Payments p
ON c.id = p.customer_id
GROUP BY p
select sum(p.amount) as total
from
customers c
inner join
payments p on c.id = p.customer_id
If there can be null values in payments.customer_id the join condition will exclude them.
Or cheaper without the join:
select sum(amount) as total
from payments
where customer_id is not null
remove group by from query..
SELECT SUM(p.amount)
FROM Customers c
JOIN Payments p
ON c.id = p.customer_id

SQL query select client that has the most orders placed

I want to select the client that has the most orders placed:
I have 2 tables :
CREATE TABLE customers(
customerid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
NAME CHAR(50) NOT NULL,
address CHAR(100) NOT NULL,
city CHAR(30)NOT NULL
);
CREATE TABLE orders(
orderid INT UNSIGNED NOT NULL,
customerid INT UNSIGNED NOT NULL,
);
This is what i am trying to do:
SELECT customers.customerid, customers.name,orders.orderid, COUNT(customerid)
AS CostumerCount
FROM customers
INNER JOIN orders
ON customers.customerid=orders.orderid;
How can i make this?
Since it is not necessarily for you what RDBMS you are using, then let me assume that you are using MySQL, and you are looking for the customer that has the highest orders count:
SELECT
customers.customerid,
customers.name,
COUNT(orders.orderid) AS Orderscount
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
GROUP BY customers.customerid,
customers.name
ORDER BY Orderscount DESC
LIMIT 1;
your create table contain wrong syntax
try this
CREATE TABLE customers(
customerid INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
NAME CHAR(50) NOT NULL,
address CHAR(100) NOT NULL,
city CHAR(30)NOT NULL
);
CREATE TABLE orders(
orderid INT UNSIGNED NOT NULL,
customerid INT UNSIGNED NOT NULL
); ^----remove comma ',' from here
and your query works good just replace COUNT(customerid) by COUNT(customers.customerid)
try it here
SELECT customers.customerid, customers.name,orders.orderid, COUNT(customers.customerid)
AS CostumerCount
FROM customers
INNER JOIN orders
ON customers.customerid=orders.orderid;
SELECT customers.customerid, customers.name,
orders.orderid, COUNT( orders.customerid ) AS CostumerCount
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
For SQL SERVER;
SELECT TOP (1) * FROM (
SELECT customers.customerid, customers.name, COUNT(*) AS CostumerCount
FROM customers INNER JOIN orders
ON customers.customerid=orders.customerid
GROUP BY customers.customerid, customers.name
) A
ORDER BY CostumerCount DESC
SELECT * FROM Customers WHERE cno = (
SELECT cno FROM (
SELECT count(*) as ordCount, cno
FROM ORDERS
GROUP BY cno HAVING ordCount >= (
SELECT max(ordCount)
FROM (
SELECT count(*) as ordCount, cno
FROM ORDERS
GROUP BY cno
)
)
)
)
I have edited the first answer because if you have more clients with the same number of orders you will only get the first one!
SELECT
customers.customerid,
customers.name,
COUNT(orders.orderid) AS Orderscount
FROM customers
INNER JOIN orders ON customers.customerid = orders.customerid
GROUP BY customers.customerid,
customers.name
HAVING Orderscount = (
SELECT COUNT(id) AS Orderscount
FROM orders
GROUP BY customerid
ORDER BY Orderscount DESC
LIMIT 1
)

SQl Query :Joining 4 Tables :One to Many

I have 4 Tables in my SQL server DB:
OrderMaster (OrderId [primaryKey], Orderdate, TotalAmount, SupplierName)
OrderDetails (OrderDetailId[primaryKey], OrderId, Item_Id, Quantity, ManufacturerId)
ItemMaster (Item_Id [primaryKey], ITem Name, ITemCost)
ManufacturerMaster (ManuId[primaryKey], ManufacturerName, HandlingFees)
The Relations are:
OrderDetails table Order id is refering the primary key of OrderMAster table(one to many)
OrderDetails table Item_Id is refering the primary key of ItemMaster
ManufacturerIdtable Order id is refering the primary key of ManufacturerMaster
Orderdetails table can have many records for one record in ORderMaster table.
Now I want to have a query to List all Orders which orderdate=05/01/2009 with the below Items as columns values:
Order number
Total Number of Items (number of child records in orderdetail table) for each order
Total (Sum of) ITemcost for all the items in an order.
How to do the Order by?
select OD.Id, count(IM.Item_Id), sum(IM.ItemCost * OD.ItemQuantity)
from OrderMaster OM
join OrderDetail OD on OD.OrderId = OD.OrderId
join ItemMaster IM on IM.Item_Id = OD.Item_Id
group by OD.OrderId
where OD.OrderDate >= '2009/05/01' and OD.OrderDate < '2009/05/02'
updated per new requirements
Something like this
SELECT
OrderMaster.OrderId,
COUNT(OrderDetailId) as TotalUniqeItems,
SUM(Quantity) as TotalItems,
SUM(ItemCost) as CostofUniqueItems,
(
SELECT ItemCost * Quantity
FROM OrderDetail od
JOIN ItemMaster im ON im.Item_Id = od.Item_Id
WHERE od.Order_Id = OrderMaster.OrderId
) as TotalCost
FROM OrderMaster
JOIN OrderDetail ON OrderMaster.OrderId = OrderDetail.OrderId
JOIN ItemMaster ON ItemMaster.Item_Id = OrderDetail.Item_Id
WHERE OrderDate >= '2009/05/01' AND OrderDate <= '2009/05/02'
I included 2 different ways to get Total Numnber of Items and the cost since I was unsure of the exact desired result.
Note, I did not check my syntax, but this should be close.