How to join + select only customers that have only 1 order? - mysql

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
)

Related

SQL - finding customer with 2 specific products bought

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

List the names of customers and the number of orders placed by customers who have placed more than 4 orders

There are two tables:
customer: cust_id and details of customer address
order- ord_id, cust_id, ord_quantity
For one cust_id there are many orders i.e many ord_id
SELECT
c.*,
o.total_order
FROM customer c
LEFT JOIN (
SELECT
cust_id,
count(*) AS total_order
FROM ORDER
GROUP BY cust_id
HAVING count(*) > 4
) o
ON o.cust_id = c.cust_id
WHERE
o.cust_id IS NOT NULL;
It should return desire result

Mysql inner query to get sum of amount

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

Multiple where clauses in select and insert

So I have a 2 tables inside of the database. The first is just a unique ID to name mapping
Customers
UID | CustomerName
In a second table I have something like the following
Orders
OrderNum | CustomerID | CustomerID2
Now I would like to insert into orders, but I only have the name of the 2 customer names, so I'm imagining something like the following (which doesnt work)
insert into Orders select null, UID as id1, UID as id2 from Customers where CustomerName=="sven";
How can I go about getting the two UID's from the first table?
Also I need to be able to do the reverse and select from the table
SELECT * FROM Orders a JOIN (Customers b) ON a.UID=b.UID WHERE b.CustomerName='sven'
Neither of these work, and I can't seem to find something similar online strangely.
UPDATE: Based on your comments if you're trying to insert two different customers' ids to one order you can do
INSERT INTO Orders (CustomerID, CustomerID2)
SELECT c1.uid uid1, c2.uid uid2
FROM
(
SELECT uid
FROM customers
WHERE customername = 'sven'
LIMIT 1
) c1 CROSS JOIN
(
SELECT uid
FROM customers
WHERE customername = 'jhon'
LIMIT 1
) c2
To select an order where one of the customers exists
SELECT o.*
FROM orders o LEFT JOIN customers c1
ON o.customerid = c1.uid LEFT JOIN customers c2
ON o.customerid2 = c2.uid
WHERE c1.customername IN('sven', 'jhon')
OR c2.customername IN('sven', 'jhon')
Here is SQLFiddle demo
Original answer: Are you looking for this?
To insert
INSERT INTO Orders (CustomerID, CustomerID2)
SELECT c1.uid uid1, c2.uid uid2
FROM customers c1 LEFT JOIN customers c2
ON c1.customername = c2.customername
AND c1.uid < c2.uid
WHERE c1.customername = 'sven'
LIMIT 1
To select
SELECT o.*
FROM orders o LEFT JOIN customers c1
ON o.customerid = c1.uid LEFT JOIN customers c2
ON o.customerid2 = c2.uid
WHERE c1.customername = 'sven'
OR c2.customername = 'sven'
Here is SQLFiddle demo
To insert into one table from another table use this syntax:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]
So in your case your query should be:
INSERT INTO Orders (CustomerID, CustomerID2)
SELECT UID, UID
FROM Customers WHERE CustomerName = 'sven';
If you want to insert multiple record from a single query you can use IN operator instead of = like this:
INSERT INTO Orders (CustomerID, CustomerID2)
SELECT UID, UID
FROM Customers WHERE CustomerName IN ('sven', 'smith');
There is a mistake in your join in the SELECT query:
You joined both tables with UID while there is no UID in Orders table. May be you mean CustomerID. Try this one:
SELECT * FROM Orders a
JOIN Customers b
ON a.CustomerID = b.UID
WHERE b.CustomerName='sven'
See this SQLFiddle

MySQL query - Join Query

Not sure how to write this join for 2 tables. Here is some sample data to illustrate:
orders
-----------------------
| order_id | customer |
-----------------------
ABC12345 1
ABC12346 4
ABC12347 3
ABC12348 2
ABC12349 2
ABC12350 3
customers
-----------------------------------
| id | name | email |
-----------------------------------
1 James james#gmail.com
2 Alice alice#hotmail.com
3 Jimbo james#gmail.com
4 Jim james#gmail.com
5 Lucy lucy#yahoo.com
I have an order_id, which I already know. Let's use the first one in the table: ABC12345. As you can see, the customer ID is 1, so that order was placed by James. Now sometimes James has ordered again using different names but we know it's him because of his email address.
So how do I retrieve all of James' orders based on his email address of james#gmail.com, if I know one of his order numbers (ABC12345)?
Edit: Not sure I stressed this enough... James has ordered 3 times, using the same email address but names of James, Jim and Jimbo. I need all of his orders using james#gmail.com as the email address.
SELECT o2.order_id
FROM orders o1
INNER JOIN customers c1
ON o1.customer = c1.id -- get the customer for the first order
INNER JOIN customers c2
ON c1.email = c2.email -- find all customers with same email
INNER JOIN orders o2
ON c2.id = o2.customer -- find all orders for those customers
WHERE o1.order_id = 'ABC12345'
You can use this:
SELECT order_id
FROM orders
WHERE customer IN (
SELECT id
FROM customers
WHERE email = (SELECT c.email FROM customers c JOIN orders o ON c.id = o.customer WHERE o.order_id = 'ABC12345')
)
You need to first quantify the person of the order to the customer table... Then, get all customer IDs by that same email... THEN get the orders that qualify those customer IDs.
select o2.*
from orders o2
JOIN ( select c2.ID
from customers c2
join ( select c1.email
from orders o
join customers c1
on o.Customer = c1.ID
where
o.order_id = 'ABC12345' ) FoundTheEmail
on c2.email = FoundTheEmail.email
) as SameCustomerEMail
on o2.Customer = SameCustomerEMail.ID
SELECT order_id
FROM orders
WHERE customer IN (SELECT customer
FROM orders
WHERE order_id = 'ABC12345')
try this since james has only one order
SELECT orders.order_id, customers.name, customers.email
FROM orders
INNER JOIN customers ON customers.id = orders.customer
WHERE orders.orer_id = 'ABC12345'
The order ID is a UNIQUE number, then you will not have two orders with the same ID, why care about the customer name?
"Every order will have a Customer's ID."