I have a pretty simple MySQL question. I have two tables, Customer and Orders. Customer table has fields (id, name) and Order has fields (id, customerID, and item).
I can find which customer bought product A and customers that bought product B with the following query in MySQL.
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product A"
Union
SELECT DISTINCT c.`id`, c.name, o.`item`, o.qty FROM `customer` as c
INNER JOIN order AS o ON (c.`Id` = o.`customerID`)
where o.`item` ="Product B"
How can find the difference and similarity in these two result sets?
1) I.e. Customers that bought only product A but did not by product B
2) I.e. Customers that bought both product A and B
Thank you for your assistance.
D
You can try using the LEFT OUTER JOIN to get the result.
Related
I have two MySQL-tables:
Persons (pid,name,companyID,companyName)
Orders (oid,companyID,details)
Now I want to count the number of order_id for each companyName as following:
Name Total
-------------------
CompanyName1 : 1200
CompanyName2 : 758
CompanyName3 : 11
I used this query but it's not working properly.
SELECT count(o.oid) as total,p.companyName
FROM orders as o, persons as p
WHERE o.companyID = p.companyID
GROUP BY p.companyName
Use join and group the result by p.companyID
SELECT p.companyName, count(o.oid) as total
FROM orders as o join persons as p
on o.companyID = p.companyID
GROUP BY p.companyID
If you are missing the companies without any orders you can use a left join.
SELECT p.companyName, count(*) as total
FROM persons p
LEFT JOIN orders o ON o.companyID = p.companyID
GROUP BY p.companyID, p.companyName
Please do not use the old, legacy join syntax any more - it is outdated since 1992.
Your data model looks messed up. That you have company ids and names in the person table but no corresponding companies table is highly suspicious.
In any case, presumably there can be multiple rows per company. You can condense the persons table and then join:
SELECT c.companyName, COUNT(*) as total
FROM orders o JOIN
(SELECT DISTINCT companyId, companyName
FROM persons p
) c
ON o.companyID = c.companyID
GROUP BY c.companyName;
However, you should fix the data model so you have a real bona fide companies table -- especially because you seem to care about that entity.
first sorry, i don't have fluid english.
I want select 3 rows in 3 different tables, two of them without Foreing Key/relation.
Need to select amount of customers in each store, and total amount of payments in these stores in one query.
Here are the tables:
Customers
Stores
Payments
I have tried these querys to get payments for each store and customers for each store, but don't know how can unify in one query:
Payments/store
SELECT count(a.payment_id) as alquileres, b.store_id
FROM customer b, payment a
WHERE a.customer_id = b.customer_id
GROUP BY b.store_id;
customers/store
SELECT count(customer_id), store_id
FROM customer
GROUP BY store_id;
But when I add count(customer_id) in unique query don't have same results.
You can use one query:
select c.store_id,
count(distinct c.customer_id) as num_customers,
count(p.payment_id) as num_payments
from customers c left join
payments p
on p.customer_id = c.customer_id
group by c.store_id;
I am just trying some practise exercises with MYSQL. I have a dataset where I would like to get the names of customers who ordered two or more different kinds of item and how many of each kind of item they bought.
The query below gives me a row for each name of the purchaser. However, I also want to display what types of items they bought and how many of them. Ideally I would like to have the same number of rows for each customer for how many different items they bought.
SELECT firstname, familyname, description, quantity
FROM customers c
JOIN orders o ON o.custID = c.custID
JOIN lineitems l on o.orderID = l.orderID
JOIN items i on l.itemID = i.itemID
GROUP BY firstname
HAVING count(description)
The query below does give me a row for each item, how many items that person bought, and the name of the purchaser. However, it does not filter for customers who only bought one specific item anymore.
SELECT firstname, familyname, description, quantity
FROM customers c
JOIN orders o ON o.custID = c.custID
JOIN lineitems l on o.orderID = l.orderID
JOIN items i on l.itemID = i.itemID
WHERE EXISTS(
SELECT *
FROM customers
GROUP BY firstname
HAVING count(description) >= 2)
Basically I would like to combine both approaches where there are multiple rows for specific item for each customer, while also filtering out customers who only bought one type of item.
If you are running MySQL 8.0, you can do a window count in a subquery and filter in the outer query, like:
SELECT *
FROM (
SELECT
c.firstname,
c.familyname,
i.description,
l.quantity,
COUNT(*) OVER(PARTITION BY c.custID) cnt
FROM customers c
JOIN orders o ON o.custID = c.custID
JOIN lineitems l on o.orderID = l.orderID
JOIN items i on l.itemID = i.itemID
) x
WHERE cnt > 1
Note: it is a good practice to prefix column names with the alias of the table they belong to; this makes the query more readable and avoid clashes when the same column name exists across tables. I made a few assumptions and updated the query accordingly.
I have a customers table (which contains customer ID and family name) and an orders table, and have to list the ID and names of customers that didn't place an order i.e do not appear in the orders table. I tried this:
SELECT custID,familyname
FROM customers
WHERE custID =
(SELECT custID
FROM orders
WHERE COUNT(custID)<1);
but am getting an error. Do I have to use NOT EXIST? Or NOT IN?
You don't have to use not exists. You should want to:
SELECT c.custID, c.familyname
FROM customers
WHERE not exists (select 1 from orders o where o.custId = c.custId);
You can also use an outer join and filter in on those instances where there is no match:
select c.custid, c.familyname
from customers c
left join orders o
on c.custid = o.custid
where o.custid is null
I have two tables:
1. customer
2. customer_order
Customer table contains customer data(duh) and customer_order contains all the orders.
I can join them on customer.id=customer_order.id_customer.
All fine, but now i want a query, where i have all the customer ids, and next the orders(customer_order.id) which these customers made (with order date)
like this:
customer 100 order 4, order 5, order 9
customer 101 order 7, order 8, order 15
I have this, but doesn't give me the result, it puts all the customer ids with an order on different rows:
SELECT c.id, c.firstname, co.id
FROM customer c
JOIN customer_order co
ON c.id=co.id_customer
;
You can use the group_concat function
select c.id, c.firstname, GROUP_CONCAT(co.id SEPARATOR ',')
from custom c
join custom_order co
group by c.id
this would return something like
customer 100 | 4,5,9
customer 101 | 7,8,15
Have you tried:
SELECT c.id, c.firstname, co.id
FROM customer c
INNER JOIN customer_order co
ON c.id=co.id_customer
ORDER BY c.id;
It's either LEFT or INNER, you'll get different results depending on which you use, and I think for your purposes LEFT is the one you want to use. Then when you retrieve the data, you might have to drop it into:
array["custid"][] = co.id