What is the difference between these two MySQL queries? - mysql

SELECT COUNT( companyId )
FROM Companies
LEFT JOIN Cities ON Cities.cityId = Companies.cityId
GROUP BY Companies.companyId;
VS
SELECT COUNT( companyId )
FROM Cities
LEFT JOIN Companies ON Cities.cityId = Companies.cityId
GROUP BY Companies.companyId;
What is the difference?

In the first query left table is Companies and in the second query Cities.
The LEFT JOIN keyword returns all rows from the left table
(table_name1), even if there are no matches in the right table
(table_name2).
FIRST QUERY
The LEFT JOIN keyword returns all rows from the Companies table
, even if there are no matches in the Cities table
SECOND QUERY
The LEFT JOIN keyword returns all rows from the Cities table
, even if there are no matches in the Companies table
Visual Representation of SQL Joins

I'm just placing a picture (self explained)
MySQL left JOIN

Related

SQL Left Join a Table on a Left Joined Table

Iam currently trying to left join a table on a left joined table as follows.
I have the tables:
accounts (id, vorname, nachname)
projektkurse (id, accounts_id, projektwochen_id)
projektkurs_einzel (id, projektkurse_id)
projektkurs_einzel_zeiten (id, date, shift, projektkurs_einzel_id)
Now I want to get every account and the amount times they have an entry inside of projektkurs_einzel_zeiten, which should also be unique. So having the same date and shift multiple times does not count as multiple entries. The result should also be limited by the column projektwochen_id from the table projektkurse. This column should match a certain value for example 8.
Some Accounts don't have any entries in projektkurse, projektkurs_einzel and projektkurs_einzel_zeiten, this is why my first thought was using LEFT JOIN like this:
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
WHERE projektkurse.projektwochen_id = 8
GROUP BY accounts.id
This query does not achieve exactly what I want. It only returns accounts that have atleast one entry in projektkurse even if they have none in projektkurs_einzel and projektkurs_einzel_zeiten. The Count is obviously 0 for them but the accounts that have no entries in projektkurse are being ignored completly.
How can I also show the accounts that don't have entries in any other table with the Count 0 aswell?
I would recommend writing the query like this:
SELECT a.id, a.vorname, a.nachname,
COUNT(DISTINCT pez.date, pez.shift) AS T
FROM accounts a LEFT JOIN
projektkurse
ON a.id = pk.creator_id AND
pk.projektwochen_id = 8 LEFT JOIN
projektkurs_einzel pe
ON pk.id = pe.projektkurs_id LEFT JOIN
projektkurs_einzel_zeiten pez
ON pe.id = pez.projektkurs_einzel_id
GROUP BY a.id, a.vorname, a.nachname;
Notes:
Your problem is fixed by moving the WHERE condition to the ON clause. Your WHERE turns the outer join into an inner join, because NULL values do not match.
Table aliases make the query easier to write and to read.
It is a best practice to include all unaggregated columns in the GROUP BY. However, assuming that id is unique, your formulation is okay (due to something called "functional dependencies").
You should not use eft join table's column ins where condition this work as inner join
You should move the where condition for a left joined table in the corresponding ON clause
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
AND projektkurse.projektwochen_id = 8
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
GROUP BY accounts.id

Very slow sql query for count

I need get report count for each user role, but my sql query very slow (40 sec on good server). My sql query:
SELECT `auth_assignment`.`item_name`, COUNT(*) as count
FROM `report`
LEFT JOIN `company` ON company.id = report.company_id
LEFT JOIN `auth_assignment`
ON auth_assignment.user_id = company.user_id
GROUP BY `auth_assignment`.`item_name`
ORDER BY `count`
auth_assignment.item_name is role type.
auth_assignment has ~23k rows.
company ~11k rows.
reports ~12k rows (one company can have many reports).
report.id and company.id, have binding
First, you are aggregating on a column from the third table in a left join. I'm guessing you don't want NULL for the value, so use inner join or change the order of the tables.
Table aliases make the query easier to write and to read:
SELECT aa.item_name, COUNT(*) as cnt
FROM report r JOIN
company c
ON c.id = r.company_id JOIN
auth_assignment aa
ON aa.user_id = c.user_id
GROUP BY aa.item_name
ORDER BY cnt;
Assuming the join's are correct for the tables, then you just want to be sure that you have indexes. These should go on the columns used for the joins: company(id, user_id), auth_assignment(user_id, item_name).

SQL Multiple columns same join column

I have a table with 3 columns in my table Travel (and of course some more):
AirportFrom,
AirportTo,
AirportFound.
The columns above display ID's from airports. In the table Airports are 2 columns AirportID and AirportName.
Instead of displaying the ID's from the airports I want to display the AirportNames.
But when I use:
SELECT id
, AirportFrom
, Airports.Airportname
, AirportTo
, Airports.Airportname
, AirportFound
, Airports.Airportname
FROM Travel
LEFT
JOIN Airports
ON AirportTo = Airports.AirportID
-- LEFT JOIN Airports ON AirportFrom = Airports.AirportID
-- LEFT JOIN Airports ON AirportFound = Airports.AirportID
It only displays the airport name of the first join in every column. I want to show the airport name for each of the 3 joins
Provide multiple aliases for joined table each time you left join, and join them as you have multiple tables:
SELECT
Travel.id,
airport_to.Airportname as to_name,
airport_from.Airportname as from_name,
airport_found.Airportname as found_name,
FROM Travel
LEFT JOIN Airports airport_to ON Travel.AirportTo = airport_to.AirportID
LEFT JOIN Airports airport_from ON Travel.AirportFrom = airport_from.AirportID
LEFT JOIN Airports airport_found ON Travel.AirportFound = airport_found.AirportID
EDIT: Replace reserved words in table aliases. Thanks for the reminder!
Your query needs table aliases (for multiple joins to the same table). Then, be sure to use qualified columns names for all columns in a query. This helps you write correct queries and it helps you and other people understand what is going on. So:
SELECT t.id, t.AirportFrom, apt.Airportname,
t.AirportTo, apf.Airportname,
t.AirportFound, apfo.Airportname
FROM Travel t LEFT JOIN
Airports apt
ON t.AirportTo = apt.AirportID LEFT JOIN
Airports apf
ON t.AirportFrom = apf.AirportID LEFT JOIN
Airports apfo
ON t.AirportFound = apfo.AirportID;

Issue SQL join query

I am getting issues with the below SQL query, unable to fetch the desired result
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
LEFT JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
The idea is to join all the AccountID(AcctID__c) in RenewalNotificationProgramDE table to the corresponding contacts in ContactNewDE table. AccountID is the foreign key in the ContactNewDE table. I am usig Innerjoin in my query as I want all AccountID to map with their corresponding contacts in ContactNewDE.
Just replace LEFT JOIN by INNER JOIN to get all AccountID with their corresponding contacts :-
Use below query :-
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
INNER JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
You have used LEFT JOIN in your query, which you need to change it to INNER JOIN. I think you would better to notice the below notes about differences between left and inner joins:
INNER JOIN: Returns all rows when there is at least one match in BOTH
tables
LEFT JOIN: Return all rows from the left table, and the
matched rows from the right table

left join sorting with NULL values

i need to sort left join by company id so that categories selected by companies will appear first.
My category table is
company_category table is
expected result should be
I am supposing below query is best solution rather than using union to show company categories on top.
SELECT * FROM category c
LEFT JOIN company_category cc ON c.category_id=cc.category_id AND cc.company_id=1
ORDER BY cc.company_id DESC