MYSQL Use 'is null' after 'on' and 'where' in 'left join' statement - mysql

I would like to filter the highest person of each sex in user table, this is the code that works fine:
SELECT s1.name, s1.sex, s1.height
FROM user s1
LEFT JOIN user s2 ON s1.sex =s2.sex AND s1.height < s2.height
WHERE s2.name IS NULL;
But this one won't work:
SELECT s1.name, s1.sex, s1.height
FROM user s1
LEFT JOIN user s2 ON s1.sex =s2.sex AND s1.height < s2.height AND s2.name IS NULL;
Is that mean 'is null' can only be used after 'where' clause?

The first version is excluding the records that do not have a matching row in the user table -- these will have a null value when you join.
The second version is filtering records where the value in the name column is null.
Visual Explanation of Joins

No.
Take a look on your second query, s2.name is not yet NULL because you are still joining the rows. Thus, the resulting value of the column can be evaluated as null or null not after it has been joined and can be filtered on the where clause.

Related

set default value on query column

I have a query with columns "Cremembers.Name" (this pulls the "Name" column from the table "Crewmembers") and "Sum of HoursUW" (this sums "HoursUW" from a different table "Marine391" per "Crewmember.Name". There is an existing relationship between Cremembers.Name and Marine391.Crewmembers where all Cremembers.Name values are listed and only values from Marine391.Crewmembers are listed where the joined fields are equal.
In this query, if a crewmember does not have any HoursUW, I want the default value of "Sum of HoursUW" to be 0.
This is the current SQL code:
SELECT DISTINCTROW Crewmembers.Name, Sum(Marine391_29ft_SAFEBOAT.HoursUW) AS [Sum Of HoursUW]
FROM Crewmembers LEFT JOIN Marine391_29ft_SAFEBOAT ON Crewmembers.[Name] = Marine391_29ft_SAFEBOAT.[Crewmembers].[Value]
GROUP BY Crewmembers.Name;
I tried using the nz() function like this:
nz((SELECT DISTINCTROW Crewmembers.Name, Sum(Marine391_29ft_SAFEBOAT.HoursUW), 0) AS [Sum Of HoursUW]
FROM Crewmembers LEFT JOIN Marine391_29ft_SAFEBOAT ON Crewmembers.[Name] = Marine391_29ft_SAFEBOAT.[Crewmembers].[Value]
GROUP BY Crewmembers.Name;
and like this:
SELECT DISTINCTROW Crewmembers.Name, nz(Sum(Marine391_29ft_SAFEBOAT.HoursUW), 0) AS [Sum Of HoursUW]
FROM Crewmembers LEFT JOIN Marine391_29ft_SAFEBOAT ON Crewmembers.[Name] = Marine391_29ft_SAFEBOAT.[Crewmembers].[Value]
GROUP BY Crewmembers.Name;
These both had syntax errors.
How can I use the nz() function or is there a better way to set the default value to 0 in this query?
Thanks in advance!!!
Apply Nz() directly to the HoursUW field as you Sum() it.
SELECT cm.Name, Sum(Nz(msb.HoursUW, 0)) AS [Sum Of HoursUW]
FROM
Crewmembers AS cm
LEFT JOIN Marine391_29ft_SAFEBOAT AS msb
ON cm.[Name] = msb.[Crewmembers].[Value]
GROUP BY cm.Name;
I did not include DISTINCTROW because the query's result set rows will already be distinct by virtue of the GROUP By.

SQL Selecting count from join returning 0 instead of null result

I have a query that gets data and also joins another table (A) and counts the rows in that join table (B). However if the main table (A) is empty I want the query to return nothing. However it is returning a result of null for id and date and an integer value of 0 for users instead of a null row. How do I get an empty result instead of it returning something?
Returning:
id | date | users
null | null | 0
SQL Code
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
An aggregate query without a group by clause always returns a single record, regardless of the content of the underlying result set (and even if it is empty).
But, since you have non-aggregated columns in the select clause (sessions.id and sessions.date), your query is missing a group by clause anyway. In non-ancient versions in MySQL, where sql mode ONLY_FULL_GROUP_BY is enabled by default, this is a syntax error.
Consider:
SELECT
`sessions`.`id`,
`sessions`.`date`,
COUNT( sessions_users.id ) AS users
FROM
`sessions`
LEFT JOIN `sessions_users` ON `sessions`.`id` = `sessions_users`.`sessions_id`
GROUP BY
`sessions`.`id`,
`sessions`.`date`
This will produce one record per session id and date, along with the count of matching records in sessions_users. If there are no records in sessions, the query will return an empty result set.
If I understand correctly, instead of NULL, you want something like this:
id | date | users
| | 0
If so, just simply use IFNULL() in your SELECT as such:
SELECT
IFNULL(`sessions`.`id`,' ') as id,
IFNULL(`sessions`.`date`,' ') as date,
....
There are also a few other ways to achieve this using just IF() or CASE .. but IFNULL is very straight forward.
BUT if you don't want to see any NULL and 0 values, change your LEFT JOIN to INNER JOIN and you're done.
From your description, it sounds like you want an inner join:
SELECT s.id, s.date, COUNT(*) as users
FROM sessions s JOIN
sessions_users su
ON su.id = su.sessions_id;

Need to join SQL table with multiple match, if value doesn't matches it should return a blank/NA value

I want to join below tables in such a way that that it should return matched value if not matching it should return a value as "NA".
below are the table details
available tables:
desired output:
Use Left Join between the tables, to consider those rows also which do not exist in the Process table.
You can use Ifnull() function, to set the value NA if no matching row (thus null value) in the Process table.
Try the following (change table and column name(s) accordingly):
SELECT r.Ticket_id,
r.Status,
r.Department,
r.Owner,
r.Process_id,
IFNULL(p.Proces_Name, 'NA')
FROM Resolution AS r
LEFT JOIN Process AS p ON p.Process_id = r.Process_id
If a value isn't found in a MySQL LEFT JOIN, the field is "filled" with NULL
The best practice, as I understand your question is IFNULL
SELECT
r.*,
IFNULL(process_name,'NA')
FROM
resolution r
LEFT JOIN processes p ON p.process_id = r.process_id
select a.ticket_id,a.status,a.department,a.ownername,
case
when b.process_name is null then 'NA'
else b.process_name
end as proces_name
from resolution_tab a
left join process_tab b
on a.process_id=b.process_id
order by a.ticket_id;

Right Join does not return all the records from right side table

I have two tables
Table 1 : assetdetail : itm_id,itm_slno,itm_desc,..
Table 2 : itmtype : typ_id,typname,..
Table2 Contains 6 different typname.
But when I use right join it returns only 4 records.
My query is :
SELECT a.itm_id,i.typname,a.itm_slno,a.itm_desc,a.itm_class from assetdetail
a right join itmtype i on i.typ_id=a.typ_id where a.itm_id!='234'
and itm_class='XYZ' group by i.typname
I need to get all the 6 typename records in the join query.What is the wrong with my query ?
In a right join, conditions on the first table need to go into the on clause, not the where clause:
SELECT a.itm_id, i.typname, a.itm_slno, a.itm_desc, a.itm_class
from assetdetail a right join
itmtype i
on i.typ_id = a.typ_id and a.itm_id <> '234' and a.itm_class = 'XYZ'
group by i.typname;
Non-matching rows in the first table have NULL values, which fail the comparisons in the where.
I would write this as a left join, however. Most people find the logic easier to follow: keep all rows in the first table, regardless of whether there is a match:
SELECT a.itm_id, i.typname, a.itm_slno, a.itm_desc, a.itm_class
from itmtype i left join
assetdetail a
on i.typ_id = a.typ_id and a.itm_id <> '234' and a.itm_class = 'XYZ'
group by i.typname;
The conditions remain the same.

SQL Query, "[...] WHERE field IS NOT NULL" shows 'field' with NULL values

I must be doing something wrong, or I don't understand the "IS NOT NULL" part, should it be showing me rows with NULL columns that I specifically wanted to no be NULL?
You are doing a left outer join on guesses. When the condition in the on is false, no row will be returned for that join and the fields referenced from that table will be null.
You have a few options I think, all depending on your needs:
Put this condition in the where clause;
Don't use the left outer join, but just a regular join;
Use coalesce to default the values.
Try use the below constructed query
select * from Tbl_EmployeeDetails where (name is not NULL or name <> 'null')
Just user regular join instead of left outer join :
SELECT guesses.*, games.* FROM games,guesses
WHERE guesses.game_id = games.game_id
AND games.real_score_team_1 IS NOT NULL AND games.real_score_team_2 IS NOT NULL ;
That should do the trick