MySQL - Joining two tables without duplicates? - mysql

I have two tables that I am trying to join. One contains a list of customers, the other is a list of orders. I am trying to formulate a query that will allow me to select all of the customers listed in the table customers who have at least one order in the table orders. However, I do not want to get duplicates for those customers who have multiple orders. Any suggestions how I can accomplish this?
I know this is probably a common issue, however I have no idea what this type of query would be called so that I could search for an answer. Any suggestions would be greatly appreciated. Thanks.

It's much simpler than you may think:
select distinct(customer_id) from orders;
Edit: If you actually want to get the full info on the customer,
select * from customers where customer_id in (select distinct(customer_id) from orders);

Use:
SELECT c.*
FROM CUSTOMERS c
WHERE EXISTS (SELECT NULL
FROM ORDERS o
WHERE o.custeromid = c.id)
The IN clause is an alternative, but EXISTS works better for duplicates because it returns true on the first duplicate so it doesn't process the entire table.

select customers.id, customers.name, count(orders.id)
from customers
inner join orders on orders.customer_id = customers.Id
group by customers.id, customers.name
having count(orders.id) > 0

SELECT
c.id,
c.name
FROM
customer c
INNER JOIN order o ON o.customer_id = c.id
GROUP BY
c.id,
c.name
HAVING
COUNT(o.id) >= 1
Can't remember if HAVING or GROUP BY comes first.

Related

SQL average and Join

I'm trying to merge these two statements into one query to get the a list of product names(or ids) against the average of their TTFF data, and I'm stuck.
select AVG(TTFF) from TTFFdata group by product_id
select product.product_name, count(*) from product join TTFFdata on product.product_id = TTFFdata.product_id
I've looked into using a temporary table (CREATE TEMPORARY TABLE IF NOT EXISTS averages AS (select AVG(TTFF) from TTFFdata group by product_id)) but couldn't get that to work with a join.
Anyone able to help me please?
You need to understand the components. Your second query is missing a group by. This would seem to be what you want:
select p.product_name, count(t.product_id), avg(t.TTFF)
from product p left join
TTFFdata t
on p.product_id = t.product_id
group by p.product_name
It is better to do group by on product_id, product_name for two reasons. One is, you can select product id along with product name. Second reason is, If the product name is not unique then it may give wrong results(this may be a rare scenario like product name is same but it differs based on other columns like version or model). The below is the final query.
select Product.product_id,
product_name,
AVG(TTFF) as Avg_TTFF
from Product
inner join
TTFFdata
on Product.product_id = TTFFdata.product_id
group by Product.product_id,Product.product_name
TTFFdata:
product:
Output:

SQL join get results that have no join aswell

I checked many posts with related questions, but couldnt find an answer.
I have 2 tables which have a one to many relationship. One is customers and the other one is projects. One customer can have many projects. their PK and FK are customer.customer_id and project_customer_id.
Now when I use the following SQL
SELECT *, COUNT(project.project_id) AS totalProjects
FROM `customer` LEFT JOIN `project`
ON `project`.`customer_id` = `customer`.`customer_id`
ORDER BY `customer`.`date_created` DESC
However when I get all my customers now it only returns the customers which actually have a project. I used inner, outer, left, union and right joins but no luck. I also tried DISTINCT but didnt work either.
Does anyone have any idea for such a query that it returns all customers even if they have no projects?
thanks in advance,
Rodney
Since you are only concerned with the count of projects "if I understood correctly from your question", either create a function to get you this count, or write a sub query like the example below...
SELECT
*,
(
SELECT COUNT(project.project_id) from project
WHERE
project.customer_id = customer.customer_id
) AS totalProjects
FROM
customer
ORDER BY customer.date_created DESC
Use this query:
SELECT *, COUNT(project.project_id) AS totalProjects FROM `customer` LEFT JOIN `project` ON `project`.`project_customer_id` = `customer`.`customer_id` GROUP BY `customer`.`customer_id` ORDER BY `customer`.`date_created` DESC
Not clear from your question, but I think you are trying to list all customers and if there are any projects associated with a customer then list the number of 'projects'? If that's your question then the below should solve it for you:
SELECT *, ISNULL((SELECT COUNT(*) FROM Project WHERE CustomerID = C.CustomerID),0) AS ProjectCount
FROM Customer C
ORDER BY C.Date_Created DESC

SQL Join, right ? left ? inner?

working with mySql I would like to list all purchases that customers made on a specific cathegory of products.
So, I had 3 tables: customers (idCustomer, Name) , cathegories (idCategory, CategoryName) and orders (idOrder, idCustomer, idCathegory, Qty, Price)
But I want a listing with ALL of the customers.
Not only the one who bought that specific idCategory
I thought something like:
select sum(Orders.Qty), Customers.Name
from Orders
right join Customers on Orders.idCustomer = Customer.idCustomer
where Orders.idCategory = 'Notebooks'
group by Orders.idCategory
but this statement only lists the records for customers who exists in Orders table.
And I want all of them ( the one who didnt buy, with qty =0 )
thanks in advance
Most people find left join easier to follow than right join. The logic for left join is to keep all rows in the first table, plus additional information from the remaining tables. So, if you want all customers, then that should be the first table.
You will then have a condition on the second table. Conditions on all but the first table should be in the on clause rather than a where. The reason is simple: when there is no match, then the value will be NULL and the where condition will fail.
So, try something like this:
select sum(o.Qty) as sumqty, c.Name
from Customers c left join
Orders o
on o.idCustomer = c.idCustomer and
o.idCategory = 'Notebooks'
group by c.Name;
Finally, the group by should have a relationship to the select clause.
Try this query
select sum(Orders.Qty), Customers.Name
from Customers
right join Orders on Customer.idCustomer = Orders.idCustomer and Orders.idCategory = 'Notebooks'
group by Customers.Name

SQL query within another query

I have a table containing customers and another containing all orders.
I want to display a list of customers and along side show the total value of their orders.
Obviously I could loop through the customers and then using PHP run another query to get each customer's revenue. I don't think this is efficient.
I am looking to achieve something like this:
SELECT username, [SELCT sum(revenue) from orders where userID=userID] from customers
And for this to show output:
bob 10000
jeff 25000
alan 500
SELECT a.username, SUM(b.revenue) totalRevenue
FROM customers a
LEFT JOIN Orders b
ON a.userID = b.UserID
GROUP BY a.username
This will list all customers with or without Orders.
To further learn more about join, please visit the article below,
Visual Representation of SQL Joins
you're close...
SELECT username, (SELECT sum(revenue) from orders where userID=c.userID) rev
from customers c
You can join the tables and the group them by the order name
SELECT o.username,
sum(revenue) as sum_revenue
from orders o
left outer join customers c on c.userid = o.userid
group by o.username
No need for a subselect with that. Try something like this:-
SELECT customers.userID, customers.username, SUM(revenue)
FROM customers INNER JOIN orders ON customers.userID = orders.userID
GROUP BY customers.userID, customers.username

Mysql query, Select all clients and their orders

Good day everyone.
A friend of mine who doesn't speak english asked me to make a question on this site for him.
Okay. His probles is: He needs to make a MySQL query to select all clients and number of their orders, or 0 if they have none.
There are two tables:
table Customers: id, name
table Orders: id, customer_id
Something like this:
client 0, 10 orders
clietn 1, 0 orders
client 2, 3 orders
And so on. But of course without text, just ordinary mysql select result.
The following will do as you asked:
select customers.name, count(orders.id)
from customers
left join orders on customers.id=orders.customer_id
group by customers.name
It basically counts the number of orders it can find for each customer.
This works because "no orders" gives NULL for Orders.id because of the LEFT JOIN.
COUNT(column) ignores NULLs so you'll get zero
SELECT
C.Name,
COUNT(O.id)
FROM
Customers C
LEFT JOIN
Orders O ON C.id = O.customer_id
GROUP BY
C.Name