I need some help with the following in SQL:
I have 3 tables which have the following data:
table name:customer
customer ID - 1,2,3,4,5,6
customer Name - customer 1, customer 2,customer 3, customer 4, customer 5, customer 6
table name: transactions
Transaction ID -1, 2,3,4,5,6,7,8
Product ID - 2,2,3,4,2,1,4,2
customer ID - 1,2,4,4,5,6,2,5
table name: product
Product ID - 1,2,3,4
product Name - product 1, product 2, product 3, product 4
I want to know which customer(s) bought product 3 and 4 - the result should be just the customer with an ID of 4.
I have the lines below, however it will only work for 3 OR 4 due to the IN function which means displays customer ID 4 and customer ID 2. I am not sure where to use the AND function in this scenario
select distinct c.customer ID
, c.customer Name
FROM transactions t
LEFT
JOIN customer c
on c.customer ID = t.customer ID
LEFT
JOIN product p
on p.product ID = t.product ID
where p.product ID IN (3,4)`
Thanks
Vishal
Straight forward: select customers that are both in the set of product 3 buyers and product 4 buyers:
select *
from customer
where customer_id in (select customer_id from transactions where product_id = 3)
and customer_id in (select customer_id from transactions where product_id = 4);
It is often faster, however, to query the transaction table only once (by aggregating it by customer).
select *
from customer
where customer_id in
(
select customer_id
from transactions
where product_id in (3,4)
group by customer_id
having count(distinct product_id) = 2
);
use joins:
Select c.CustomerName
from Customer c join Transacation t
on c.Customer_ID = t.Customer_ID
where Product_ID in (3,4)
group by c.CustomerName
having count(distinct Product_ID) = 2
Another way, but not so optimal:
select *
from customer
where customer_id in (select customer_id from transactions where product_id = 3
INTERSECT
select customer_id from transactions where product_id = 4);
One possible query to do that is the following. The inner subquery extracts only customers who have the two products (see last WHERE A.RC=2), simulating the sort of "and condition" you need.
SELECT DISTINCT A.customer_ID, C.customer_Name
FROM (SELECT customer_ID, COUNT(DISTINCT product_ID) AS RC
FROM transactions
WHERE t.product ID IN (3,4)
GROUP BY customer_ID) A
INNER JOIN transactions t ON A.customer_ID = t.customer_ID
LEFT JOIN customer c on c.customer ID = A.customer ID
LEFT JOIN product p on p.product ID = A.product ID
WHERE A.RC=2 AND t.product ID IN (3,4)
You need this instead of IN
where p.product ID = '3' AND p.product ID ='4'
IN uses the OR logic between values thats why you're returning both
Related
CUSTOMERS
NAME
ID
ORDERS
CID
ITEMS
New customer orders in orders table have new data record like:
CID 134 - CAR
CID 135 - PHONE
CID 134 - TEA
I need to select only customers that have 1 record in the orders table, in dat above its CID 135
IDN=CID
I need to select IDN that have only one ITEMS record, I tried:
SELECT customers.name, orders.items
FROM customers JOIN orders
WHERE Items > 2
but doesn't work :(
You just need to modify your where clause. This query will return only customers that have exactly one row in the orders table.
SELECT customers.name,
orders.items
FROM customers
LEFT JOIN orders
on customers.ID = orders.CID
WHERE customers.ID IN (SELECT CID from orders GROUP BY CID HAVING COUNT(*) = 1)
Try adding an ON statement for your join. This tells SQL how to connect the two tables.
SELECT
customers.name
, orders.items
FROM customers
JOIN orders
on customers.ID = orders.CID
WHERE Items > 2
You must add a another subquery which count the numbers,
CREATE tABLE customers (ID int, name varchar(10))
INSERT INTO customers VALUES (1,'A'),(2,'b')
CREATE tABLE orders (ID int,CID int,items varchar(10))
INSERT INTO orders VALUES (1,1,'car'),(2,1,'car2'),(3,2,'car'),(4,2,'car2'),(5,2,'car2')
SELECT
customers.name
, orders.items
FROM customers
JOIN orders
on customers.ID = orders.CID
INNER JOIN (SELECT COUNT(*) countr,CID FROM orders GROUP BY CID) o1 on o1.CID = orders.CID
WHERE countr > 2
name | items
:--- | :----
b | car
b | car2
b | car2
db<>fiddle here
You can do:
select * from customers
where id in (
select cid from orders group by cid having count(*) = 1
)
SELECT avg(Product.product_price)
From product
Where (
SELECT from customer
customer.city = "Tucson"
and Customer.cust_id = orders.cust_id
and Product.product_id = Orderline.product_id
)
group by product_name
UNION
SELECT sum(product.product_price)
From product
Where (
SELECT from customer
customer.city = "Tucson"
and Customer.cust_id = orders.cust_id
and Product.product_id = Orderline.product_id
)
group by product_name
I'm trying to display the average order from customers who order from tucson and the sum of the products going to tuscon
I have these tables with these (rows )orders (order_id, order_date, cust_id), product (product_id, product_name, product_price), orderLine (order_id, product_id, quantity), customer (cust_id, cust_name, street, city, state, zip) I need to 8. Show the average price and total price of products bought by customers from ‘Tucson’(Use Union) –
The problem is not with UNION - it's with the two queries you're attempting to UNION together. It looks to me like the AVG query should be something like:
SELECT avg(p.product_price)
From product p
INNER JOIN orderline ol
ON ol.product_id = p.product_id
INNER JOIN orders o
ON o.??????? = ol.???????
INNER JOIN customer c
ON c.cust_id = o.cust_id
WHERE c.city = 'Tuscon'
What's not clear from the code you posted is how the orders and orderline tables are to be joined - that is, what the common field(s) are in those tables. You'll need to fill that in.
Make similar changes to your SUM query.
Here's my orders table:
I want to select all orders excluding very first order of each customer (if customer has placed multiple orders).
So if a customer e.g. 215 has total 8 orders, then I will select his all last 7 orders excluding his very first order 70000 which was placed on 10 July 2017.
But if a customer e.g. 219 had placed only one order 70007, it must be selected by the query.
Using an anti-join approach:
SELECT o1.order_id, o1.customer_id, o1.order_date, o1.order_value
FROM orders o1
LEFT JOIN
(
SELECT customer_id, MIN(order_date) AS min_order_date, COUNT(*) AS cnt
FROM orders
GROUP BY customer_id
) o2
ON o1.customer_id = o2.customer_id AND
o1.order_date = o2.min_order_date
WHERE
o2.customer_site = 1 AND
(o2.customer_id IS NULL OR
o2.cnt = 1);
The idea here is to try to match each record in orders to a record in the subquery, which contains only first order records, for each customer. If we can't find a match, then such an order record cannot be the first.
You can try below -
select order_id,customer_id,order_date,order_Value
from tablename
group by order_id,customer_id,order_date,order_Value
having count(order_id)=1
union all
select order_id,customer_id,order_date,order_Value
from tablename a where order_date not in (select min(order_date) from tablename b
where a.customer_id=b.customer_id)
Solution
Dear #Tim Biegeleisen, your answer almost done. just add HAVING COUNT(customer_id)>1
So the query is below:
SELECT o1.order_id, o1.customer_id, o1.order_date, o1.order_value
FROM orders o1
LEFT JOIN (
SELECT customer_id, MIN(order_date) AS min_order_date
FROM orders
GROUP BY customer_id
HAVING COUNT(customer_id)>1
) o2
ON o1.customer_id = o2.customer_id AND
o1.order_date = o2.min_order_date
WHERE
o2.customer_id IS NULL;
I have three tables which are interlinked :
1) First is order table that contains 2 columns, id and vendor_id
2) Second table is order_products that contains product detail of order table and has columns order_id (foreign key of id from order table) and product_id.
3) Third table is vendors_product that contains prices of products for different vendor like vendor_1 has $10 for product_a and vendor_2 has $20 for product_a so each vendor has different prices of same products. This table has columns, vendor_id (foreign key of vendor_id from order table), product_id (foreign key of product_id from order_products table) and product_amount columns
Now I want to get the sum of product_amount for all order and should be based on vendor of each order.
I tried this by using below query but I couldn't get the result
SELECT
a.id, a.vendor_id, (
SELECT
SUM(product_amount)
FROM
vendors_product
WHERE
vendor_id = a.vendor_id
AND product_id IN (
SELECT
product_id
FROM
order_products
WHERE
order_id = a.id
)
) as total_price
FROM
`order` a
Can somebody help me out ???
Try this:
SELECT o.id, o.vendor_id, SUM(product_amount) product_amount
FROM `order` o
INNER JOIN order_products op ON o.id = op.order_id
INNER JOIN vendors_product vp ON a.vendor_id = vp.vendor_id AND op.product_id = vp.product_id
GROUP BY o.id, o.vendor_id;
Try this:
SELECT a.id, a.vendor_id, SUM(product_amount) AS 'product amount'
FROM `order` a
INNER JOIN order_products vp1 ON a.id = vp1.order_id
INNER JOIN vendors_product vp2 ON a.vendor_id = vp2.vendor_id AND vp1.product_id = vp2.product_id
GROUP BY a.id, a.vendor_id
I've got 2 tables: Online Orders, Online orders details
I have an issue on how to calculate the total amount of the order in Online Order table based on the detail order table.
The detail table looks like:
id_order Id_product quantity price value
1 2 1 3 3
1 3 2 2 4
2 1 1 5 5
I would like to sum all the values from an id_order and insert them into the total amount of the order in the Online orders table.
Can you help me with the SQL command?
It's not clear what database system you use.
If you want to UPDATE orders.total_amount
This update statement will work under any DB:
update orders
set total_amount = (
select SUM(value)
from orders_details
where id_order = orders.id
)
where EXISTS(select *
from orders_details
where id_order = orders.id)
This update statement works under MySQL:
update orders u
inner join (select id_order, SUM(value) as total
from orders_details
GROUP BY id_order) s on
u.id = s.id_order
set u.total_amoun = s.total
Is this what you want?
SELECT o.id_order, SUM(quantity * price) AS total_price
FROM online o
INNER JOIN detail d
ON d.id_order = o.id_order
GROUP BY o.id_order