SQL Left join not displaying all rows from left - mysql

So a rough structure of my two tables concered is as follows:
Table one: Services
services.id
services.name
Table two: Orders
orders.id
orders.item
orders.service
Table one contains a list of services. And table two is a list of orders. I am trying to generate a list of all orders for services from table two (orders) but also include (Zero) the services that haven't been ordered. I'm aware that that's where the LEFT JOIN comes but it doesn't seem to be working at all. It displays most of the services but there's one or two records (from services) not being displayed. Here's the query i'm using so far..
Any guidance at all is much appreciated, thanks!
select services.name,count(orders.service)
from services
LEFT JOIN orders ON services.id=orders.service
WHERE item IN (1,2,3,4)
group by statuses.service;

Your original selection is fine and should allow all records from the services table through. However you're then restricting this by your where clause. If there was no join for a specific row, item will have a NULL in it which your WHERE clause is filtering out.
SELECT services.name
,COUNT(orders.service)
FROM services
LEFT JOIN orders ON services.id = orders.service
WHERE item IS NULL
OR item IN ( 1, 2, 3, 4 )
GROUP BY statuses.service;
Forgive me if slightly wrong, I'm coming from SQL Server background.

First of all, I believe you've got a typo - statuses.service should be services.name, right?
Since item is a column from the orders table, you should put it in the join condition:
select services.name,count(orders.service)
from services
LEFT JOIN orders ON services.id=orders.service and services.item IN (1,2,3,4)
group by statuses.service;
Otherwise, you filter out the services without orders or whose orders only have items not in (1,2,3,4).
Kind regards, Frank

Related

How Should I Combine These Two SQL queries into one?

I am trying to make an INNER JOIN statement that will join two tables, the Orders table and the Customer table, these both share the value/key of CustomerID. The Customer table has the information for which state a customer lives in. The Orders table has the information for which customer, according to their customer ID, bought which product. I need to find which products are the top 3 most popular in certain states. Please find the table descriptions images below, so you can understand what I mean.
Orders table:
Customer table:
How can I make this INNER JOIN statement and include the logical operators (and/or) to make this happen?
Thanks!
Try this,
SELECT column_name(s)
FROM Customer
INNER JOIN Order
ON Customer.CustomerID= Order.Customer_ID AND <conditions>;
Inner Join is just only 1 way of joining 2 tables. You can also join these two tables using WHERE closure as follows,
SELECT column_name(s)
FROM Customer c, Order o
WHERE c.CustomerID = o.Customer_ID AND <condition>

SQL to show even null record

Below is my sql statement
SELECT a.purchase_id,
b.username,
a.purchase_packageid,
a.purchase_tradelimit,
a.purchase_pincode,
a.purchase_datetime,
c.packages_name ,
FROM purchase a,
accounts b,
packages c
WHERE a.purchase_userid=b.UserId
AND c.packages_id=a.purchase_packageid
Basically the issue is I got 3 tables
Accounts
Purchase
Packages
The main table is Purchase, inside the table there is purchase_userid , which I need to use it to get username from table accounts
So the problem now is I got rows where the purchase_userid is blank, because its blank, it won't draw its record as null.
The only record that show in this sql statement is only those with purchase_userid,
As the value for purchase_userid will be fill up later for my web app,
I still want to select rows without purchase_userid and those with purchase_userid
Thanks for helping !!
You need to use a left join to load all records in Purchase even when no matching records are found in Accounts.
SELECT a.purchase_id, b.username, a.purchase_packageid, a.purchase_tradelimit, a.purchase_pincode, a.purchase_datetime, c.packages_name
FROM purchase a LEFT JOIN accounts b
ON a.purchase_userid=b.UserId
JOIN packages c
ON c.packages_id=a.purchase_packageid
This post explains the different kinds of joins pretty well: What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN?
You're using the old-timey syntax for INNER JOINs between your tables, when what you need is LEFT JOIN operations. Try this:
SELECT a.purchase_id,
b.username,
a.purchase_packageid,
a.purchase_tradelimit,
a.purchase_pincode,
a.purchase_datetime,
c.packages_name
FROM purchase AS a
LEFT JOIN accounts AS b ON a.purchase_userid = b.UserId
LEFT JOIN packages AS c ON a.purchase_packageid = c.packages_id
This works better for you because the kind of JOIN you were using suppresses records from your a table when they weren't matched in your b or c table. This LEFT JOIN will leave the a table records in place, and put NULL values where you are calling for data from the other two.

SQL querying multiple tables for information

I have a little dilemma in joining data from 4 tables in one SQL query, I am using MySQL for the DB part and would appriciate any help you can give me.
Here is the task...
I have for tables with columns and data
Sale Items Owner Salesman
-------------- ----------- ----------- --------------
*Salesman_id Item_type *Owner_id *Salesman_id
*Owner_id Item_color Owner_name Salesman_name
Buyer_id *Owner_id
Price
I want to query these tables on the columns I have marked with emphases text. So I can get result like
Item type, Item color, Owner name, Salesman name, Salesman number.
I have gone through a countless number of iteration trying to achieve this both with JOIN and nested queries without sufficient result.
If there is a one-to-one relation you can use inner join
SELECT i.Item_type , i.Item_color ,o.Owner_name,sm.Salesman_name,sm.Salesman_id
FROM Salesman sm
INNER JOIN Sale s ON (s.Salesman_id = sm.Salesman_id )
INNER JOIN Owner o ON (s.Owner_id=o.Owner_id)
INNER JOIN Items i ON (i.Owner_id=o.Owner_id)
If there is one -to- many try with Left join
try this
SELECT Item_type, Item_color, Owner_name, Salesman_name, Sale.Salesman_id FROM Items
INNER JOIN Owner USING(Owner_id)
INNER JOIN Sale USING(Owner_id)
INNER JOIN Salesman ON Salesman.Salesman_id=Sale.Salesman_id
why doesn't the Items table have a primary key?
A solution when we're not joining, and you want it them to just display their values, you can do something like (I know this doesn't directly answer OP's question, but I'm getting there...)
SELECT sale.`salesman_id`,sale.`owner_id`,
items.`order_id`,
owner.`owner_id`,
salesman.`salesman_id`
FROM `Sale` sale,
`Items` items,
`Owner` owner,
`Salesman` salesman
And that should return everything.
However, your question states that we are joining. Could you put some data into something like SQLFiddle so I have some visual representation? and a brief summary of what you're trying to accomplish - as in where you want the joins?

Join Orders, Staff's first and last name, item and location MySQL

Join Orders, Staff's first and last name, item and location into one so I can export the content into an Excel spreadsheet.
SELECT orders.order_id, staff.staff_id, staff.first_name, staff.last_name, items.name, locations.address1, locations.address2, locations.state, locations.zip_code, orders.created_at
FROM orders
INNER JOIN staff
ON orders.staff_id = staff.staff_id
INNER JOIN items
ON orders.item_id = items.item_id
INNER JOIN location_staff
ON location_staff.staff_id = staff.staff_id
INNER JOIN locations
ON location_staff.loc_id = location.loc_id
I am trying to gather this information to put into an excel document but my query is not returning any results. Any help would be appreciated.
Here is An ERD diagram for further understanding
https://www.dropbox.com/s/7inma4s42xq5t4a/ERD.jpg
(Location_staff_link was shortened when created to location_staff)
jsut remove the extra tables in your FROM clause,
SELECT orders.order_id,
staff.staff_id,
staff.first_name,
staff.last_name,
items.name,
orders.created_at
FROM orders
INNER JOIN staff
ON orders.staff_id = staff.staff_id
INNER JOIN items
ON orders.item_id = items.item_id
INNER JOIN locations
ON location.staff_id = staff.staff_id
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Nothing in your query looks bad, so here is what I suggest to find the answer in this sort of case.
First reduce to the bare minimum of the first join and change the fields to select * (temporarily, you can go back to the real fields as soon as you find the issue) so you can se all the data.
Do you get records, then add in any where clauses on the tables in that join. Do you still get records?
Then add in each join and each where clause one at a time until you find the one where the records disappear. This will tell you what you need to do to fix it.
Often in a case like this where no records are returned, one of the joins needs to be a left join or there is no data that meets the terms of the where clauses or one of the joins is improperly defined. And sometimes, there is a problem in that your database does not have the data you were expecting it to have. But first you have to use the process above to diagnose where the problem is.

MYSQL - A little bit of trouble/confusion with join query

I am trying to put together a mysql query, that links 3 tables together. In essence, the tables are as follows:
products - Contains product information and basic pricing.
product_depts - Linking table that links products to different departments.
promotions - Another linking table, links promotion periods and prices based on product id.
This is the query:
SELECT p.id, `desc` , price1, price2, cost1, taxable, quantity, deptId, sale
FROM products p
INNER JOIN product_depts ON p.id = prodId
INNER JOIN promotions s ON p.id = s.id
WHERE MATCH (
`desc`
)
AGAINST (
'CLOVER'
IN BOOLEAN
MODE
)
ORDER BY `desc`
LIMIT 0 , 30
If the following line is removed:
INNER JOIN promotions s ON p.id = s.id
And sale taken out of the select clause,
What happens, is ALL the products with a description containing "CLOVER", in the products table, are returned.
With the addition of the removed query parts, only the items that are on promotion (have a matching id in the promotions table), are returned. And any additional products containing "CLOVER" in the products table, that are not "on promotion" are left out.
As I have very limited knowledge with mysql, I thought maybe someone that does have a great deal of knowledge on the matter to share... Would like to provide some input with this.
As i understand it though, this would be essentially the same thing as calling deptId from the product_depts table, which works perfectly. So it is confusing me.
What am i doing wrong that only the items that are "on promotion" are displayed and the additional results are left out?
Thank you!
INNER joins basically say "retrieve all records where there's a matching record in BOTH tables".
If I'm reading your question correctly, it sounds like what you'd want is a LEFT or RIGHT join, which translates to "retrieve all records from one table, and (if any) matching records from the other table.
Sounds like you want to get all products, whether they have a promotion or not, but if they do have a promotion, retrieve the promo info as well.
That'd be
SELECT ...
FROM products
INNER JOIN product_depts ON ...
LEFT JOIN promotions ON ...
So... all products MUST have a department, so do an inner join for that particular part of the query. The left join on promotions makes the 'products' table be the LEFT table, so all records from that table are fetched. The promotions table becomes the RIGHT table, and only provides data for the query results if there's a matching record in the promotions table.
So... given 2 products, 1 of which is on sale, you'd get
product #1 department #1 promoinfo #1
product #2 department #2 NULL
for results. Since there's no matching promo information for the #2 product, you get NULL for the promo data.