MySQL Queries and 2 separate tables - mysql

So I have 2 tables in a MySQL database, one for "Users" and the other for "Orders", where each entry in Orders is an order placed by a User (Some users can have multiple orders, while some might not have any). I am working on reporting queries and one of the reports I want is a list of Users that have never placed any orders. I am still a bit of a beginner when it comes to MySQL queries, so I am not sure how to do this one. The query will be placed via PHP if that makes any difference.
Here are my columns in each table (simplified):
Users:
ID
Name
Orders:
OrderID
OrderName
CustomerID (corresponds to User.ID that placed the order)
Any help here would be great. Thanks!

Use a LEFT JOIN on Orders and check whether OrderId is null:
SELECT U.*
FROM
Users U
LEFT JOIN Orders O ON(U.ID = O.CustomerID)
WHERE
O.OrderId IS NULL
SQLFiddle

SELECT ID, Name
FROM users
WHERE ID NOT IN (SELECT DISTINCT customerID FROM Orders)

So basically you'are looking for orders that are not made by that user
Select * from Orders where CustomerID = 5 //5 is the id of the custumer
If you are doing a search by name
Select * from Orders LEFT JOIN Users on Users.ID Where Users.name ='Mark'
If no results, it mean that customer never ordered anything

Try
SELECT U.*
FROM Orders a
RIGHT JOIN Users b
ON b.ID = a.CustomerID
WHERE a.OrderId IS NULL

Related

How To Select Records that Don't Exist In a Table in SQL?

I have 2 SQL tables with the following columns:
"users":
userid, firstname, lastname
"orders":
orderid, userid, orderdate, shippingdate
I've been told I can use a join to achieve what I am looking for, but I don't see how a join would work.
The idea is to select all users from "users" that have NOT placed an order; users that do not have a row in the "orders" table as defined by the userid.
This is all I have so far:
select users.userid, users.firstname, users.lastname, orders.*
from users
join orders on orders.userid = users.userid
But that only returns users who DID place an order. How would I expand upon that to get the users that HAVEN'T placed an order? From what I understand, a join is meant to get MORE information, not the lack thereof.
Some info:
I'm using the latest version of HeidiSQL on Windows 10.
You don't need a join to do this, Do:
select * from users where userid not in (select userid from orders)
You can use LEFT JOIN also:
SELECT * FROM users
LEFT JOIN orders ON users.userid= orders.userid
WHERE orders.users IS NULL

How to merge two tables before doing a inner join?

TABLE user
- id
- username
- email
- passwd
TABLE user_external
- id
- username
- email
- passwd
TABLE orders
- id
- user_id
- product
I have two tables containg userinformation i want to merge in order to get usersname on a order.
my select only fetches the name from the user table (and leaves the ones from external blank), but not the user_external.
Is there a way to UNION users tables, and then do a left join?
select
orders.product,
merged_user_table.name as name
FROM orders o
LEFT JOIN merged_user_table user_assigned_to ON o.user_id = merged_user_table.id
WHERE
orders.id = 1
The following should work:
SELECT
orders.product
,merged_user_table.name as name
FROM orders o
LEFT JOIN (
SELECT id,username,email,passwd
FROM user
UNION ALL
SELECT id,username,email,passwd
FROM user_external
) merged_user_table user_assigned_to
ON o.user_id = merged_user_table.id
WHERE
orders.id = 1
I have assumed that the user and user_external tables' users are distinct. Using UNION without ALL will effectively perform a SELECT DISTINCT between the two selects in the subquery, which would be less efficient.
While you can use a sub query the get a unioned table, then join that to orders, this does mean the main join won't use an index.
As such I would probably use 2 separate queries, one joining orders with user and the other joining orders with user_external, and union the results together.
This should work (using an INNER JOIN rather than a LEFT OUTER JOIN - can't see why you are using a LEFT OUTER JOIN but there might be a reason). You have specified to bring back a column called name, but neither user table has such a column so not sure if you mean to bring back the user name or the table name - so the below example SQL brings back both.
SELECT orders.product,
user.username as name,
'user' as table_name
FROM orders o
INNER JOIN user
ON o.user_id = user.id
WHERE orders.id = 1
UNION ALL
SELECT orders.product,
user_external.username as name,
'user_external' as table_name
FROM orders o
INNER JOIN user_external
ON o.user_id = user_external.id
WHERE orders.id = 1

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

Select rows that are referenced in another table

I have two tables and they are as follows:
USERS
ORDERS
I want select all users who have at least 1 order or more in the ORDERS table. I know there is an inline query for this in MySQL, but right now I have to select all users and then make another query seeing if each user has an order - all this using a PHP loop.
What I am doing now is not ethically correct, so I basically just want to select all users who have been referenced in the ORDERS table in ONE MySQL query.
This is a query you should be using
select distinct u.* from users u
inner join orders o on o.user_id = u.id;
Note the distinct and u.*. This query will not select fields from orders and it will not select the same user twice (if one has more than one order).
Demo: http://sqlfiddle.com/#!2/6ebcc/3
You can use mysql join syntax. Assuming both of your tables has userid column, this is the example :
SELECT * FROM USERS a JOIN ORDERS b ON
a.UserId = b.UserId
This is a simple database operation, see here for the explanation join

MySQL Left Join Multiple Rows

I have an interesting challenge... I have two tables, products and users.
products contains 2 columns, user_id and current_bidder, which hold two different IDs from the users table.
I would like to select all columns from products, and the name and rating from the users table for each user_id and current_bidder.
Essentially, I'm trying select columns from two different rows on a joined table, while disambiguating their names.
Any help would be greatly appreciated.
Join to the user table twice, and give each copy a different alias. Something like this:
select p.name, p.weight, owner.name, bidder.name
from product p
join user owner
on ...
join user bidder
on ...
The nice way to avoid ambiguity between columns is to add an ALIAS on it.
SELECT a.*, -- selects all records from products
b.name AS user_name, -- user_name is an alias of users.name (user_id)
c.name AS bidder_name -- user_name is an alias of users.name (current_bidder)
FROM products a
LEFT JOIN users b
ON a.user_id = b.id
LEFT JOIN users c
ON a.current_bidder = c.id
The reason why I used LEFT JOIN is because I assumed that some products has no bidder yet. If INNER JOIN was used, product will never be shown on the result until there's a bidder on it.