LEFT JOIN does not return EXPECTED RESULT - mysql

I wrote a query to update the imageSrc of an object on database : UPDATE BOXES SET BOXES.IMAGESRC = ?1 WHERE BOXES.ID = ?2 , and it actually works, because I checked on the database my table Boxes and it updated correctly the imageSrc of the Box with ID=1.
(Result here)
My problem comes when I execute the following LEFT JOIN query SELECT * FROM BOXES AS A LEFT JOIN MATCHES_BOXES AS B ON A.ID=B.MATCH_ID WHERE B.MATCH_ID LIKE ?1 Because it gives me the Box with ID=1 with is OLD imageSrc (Result of LEFT JOIN)
As you can see, the BOX with ID=1 does not cointains the correct imageSrc (/resources/images/cards/blue-01.png), instead, it cointains the old imageSrc (/resources/images/celda.png)
And it does not make sense to me, because I LEFT JOINED with the table Boxes, where the Box with ID=1 already have the correct imageSrc, but returns the old.

This happens as your where clause on the left join converts the query into an inner join.
SELECT *
FROM BOXES AS A
LEFT JOIN MATCHES_BOXES AS B
ON A.ID=B.MATCH_ID
WHERE B.MATCH_ID LIKE ?1
Analyze the scenarion, if you wanted to get recrods in Boxes regardless of whether it was present in MATCHES_BOXES then the resulting rows from B will all have been NULL for the missing MATCH_ID in B(ie no_row_exists).
But since you got a WHERE B.MATCH_ID LIKE '?1' condition after the JOIN, it will negate those missing MATCH_ID as you are basically check WHERE NULL like '?1' and since NULL cannot get equated with anything, the missing recrods are not retreived in the query.
If your intention is to get all records from BOXES even if they dont exist in MATCHES_BOXES, and also those records from BOXES which exist in MATCHES_BOXES on the ID and you wish to bring them only if MATCH_ID LIKE '?1', the you would JOIN on the AND condition as follows
SELECT *
FROM BOXES AS A
LEFT JOIN MATCHES_BOXES AS B
ON A.ID=B.MATCH_ID
AND B.MATCH_ID LIKE ?1 /*use AND instead of WHERE*/

The outer join doesn't seem to make much sense. Anyway, you are selecting MATCHES_BOXES looking for a particular MATCH_ID (3 in your sample result). You join the BOXES table on the same column. Thus you are showing BOXES with the ID 3. MATCHES_BOXES also has a column BOXES_ID. This has nothing to do with the joined BOXES row, however. When you see the IMAGESRC for BOXES row for ID 3, it is because you are joining this row.
I suppose you simply want to join on BOXES_ID instead:
SELECT *
FROM boxes b
JOIN matches_boxes mb ON mb.boxes_id = b.id
WHERE mb.match_id = ?1;

Related

Why in the left join the result shows a few rows under a column null

I am trying to practice left join and facing issues with the null values.
These are two tables and have few details common highlighted in red
1st try - When I run an inner join, I get correct results matching 4 rows in red
Query is as under
select * from empl1
inner join empl2 on empl1.empl_code=empl2.empl_code
2nd try - When I run a left join, I get all the 4 rows which are common, but rest 6 rows shows all null values- please see the query as under
select * from empl2
left join empl1 on empl2.empl_code=empl1.empl_code
3rd try - When I run a left join mentioning the column titles I get full values in all the columns except in designation column. In designation column, I get null values except for matching rows. Please see the query as under
SELECT empl1.empl_code, empl1.fullname, empl2.designation, empl1.salary, empl1.department, empl1.tablename
FROM Empl1
left join empl2 on empl1.empl_code = empl2.empl_code
Results for Try 1 and Try 2
Why am I facing problem in left join with null values? why the 2nd time I get values in all the columns and get null in designation?
Please help me understand
Left join will give you all the records from left table and null for records which don't match.
In your Try 3, you are selecting empl2.designation, hence you are getting null for non matching records.
And in try 2, you won't get null, if you just select empl2.* from empl2 left join..... I belive you didn't give exact screenshot.
I encourage you to create demo on rextester.com and share your work if you have any other doubt.
It is because in the first statement your LEFT JOIN is on the empl2, and your first column is empl2.empl_code being NULL, instead in the second statement your LEFT JOIN is on your table empl1, your first column is empl1.empl_code. Use the same table with the LEFT JOIN and you will see the same result.

LEFT JOIN two columns from one table on two separate tables

I'm not sure if this is possible exactly as stated in the title, but what I'm trying to accomplish, however possible, is what would amount to left joining two columns from one table, each on a separate table.
Here's the statement I'm working with. Unfortunately, MySQL doesn't allow me to actually do this and gives me an error message. Is there another way to accomplish what I want? Is my syntax perhaps just off?
select h.HITTER_ID, u.UMPIRE_ID, u.HAND_B
from
hitters h,
schedules sched
LEFT JOIN
umpires u
ON sched.home_base_umpire_id = u.UMPIRE_ID and h.HAND_B = u.HAND_B
In the umpires table, each UMPIRE_ID appears twice, once with HAND_B = "R" and once with HAND_B = "L"
Essentially, I want to:
1) Pull the UMPIRE_ID from umpires when that UMPIRE_ID appears in schedules
2) Of the two UMPIRE_ID records, select the one with the HAND_B field that corresponds to the HAND_B field in hitters
I could put the "h.HAND_B = u.HAND_B" in the where clause, but that would require that the UMPIRE_ID not be NULL, and I need to leave open the possibility that it is NULL.
How can I accomplish this?
You need to modify your query to be like below
select h.HITTER_ID,
u.UMPIRE_ID,
u.HAND_B
from hitters h
left join umpires u on h.HAND_B = u.HAND_B
left join schedules sched ON sched.home_base_umpire_id = u.UMPIRE_ID;

Select from 3 tables if result is empty

I'm using 3 tables to collect data from. The proces looks like:
User write VIN to form
Script search in table 1 for case_id and country base on that vin
number
After that he use case_id and country for search in table number 2
and get calculation id from there
Base on that calculation id and case id it search in 3th table
.
My script looks like this:
SELECT
cases.case_id,
cases.lastcalc_model_options,
cases.country,
calculations.calculation_id,
calculations.license,
positions.text
FROM cases
INNER JOIN calculations ON(cases.case_id =calculations.case_id
AND cases.country = calculations.country)
INNER JOIN positions ON(calculations.case_id = positions.case_id
AND calculations.calculation_id = positions.calculation_id)
WHERE vin ='ABCDEFGH'
This select work correctly, problem start when for example there is for example no result in table positions with that case_id and calculation_id. Instead of give back atleast everything it found in other tables it return NOTHING.
Is there a way to change this kind of komplex SELECT to return everything it found not return something only when every condition is TRUE?
Your problem is the INNER JOIN. Using INNER JOIN your result only contains entries present in all tables. Try using LEFT JOIN instead.
SELECT
cases.case_id,
cases.lastcalc_model_options,
cases.country,
calculations.calculation_id,
calculations.license,
positions.text
FROM cases
LEFT JOIN calculations ON(cases.case_id =calculations.case_id
AND cases.country = calculations.country)
LEFT JOIN positions ON(calculations.case_id = positions.case_id
AND calculations.calculation_id = positions.calculation_id)
WHERE vin ='ABCDEFGH'
See this stackoverlow answer for some more indepth information.
INNER JOIN returns rows from both tables only if there is a match between the columns in both tables.
You may try LEFT JOIN or FULL OUTER JOIN instead.

In joins if specific column is null than in return resulting query does not retun a whole row

I am trying to get records from multiple tables. If "im.path" column is null in the db against the specific id, then in result whole row is skipped.
I want that if image does not exit against the specific id, then in result it shows the row with a image path column empty.
My query is below.
select distinct p.person_id as p_id,i.current_status,p.*, im.path from invitation i
join person p on i.person_id=p.person_id
join user u on p.person_id=u.person_id
join image im on u.user_id=im.entity_id
where sender_account_id=40 or i.person_id=40 and invitation_category_id=1
In this case if im.path column is empty, then whole record is skipped, that is what I do not want
Thanks in Advance.
SELECT distinct p.person_id as p_id, i.current_status, p.*, im.path
FROM invitation i
INNER JOIN person p on i.person_id=p.person_id
INNER JOIN user u
on p.person_id=u.person_id
LEFT join image im
on u.user_id=im.entity_id
WHERE (sender_account_id=40
or i.person_id=40)
and invitation_category_id=1
I'm also suspicious of not having ()'s around the OR statement here; so I added them.
also without knowing where sender and invitation_category_ID reside, they may limit the results inappropriatly from the left join. So what table are sender_account and invitation_category_ID in?
http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ is a great link explaining join types.

MySQL LEFT JOIN with optional value in second table

I have two tables: projects and user_licenses.
I'd like to grab the entire list of projects from the database, as well as the user's current license state. The licenses table has a user ID field which I check against a $_SESSION variable for the value. The thing is, they might not have a license, or a non-logged in visitor may want to see the projects list. My question is this: How can I get the data from the left table always display, but only grab data for that row from the right table when certain conditions are met?
The query I have at the moment is this:
SELECT Projects.*,
UserLicenses.*
FROM Projects
LEFT JOIN UserLicenses ON Projects.id = UserLicenses.project_id
WHERE UserLicenses.user_id = 12
ORDER BY name ASC
Add any extra conditions to the on clause of the left join. They will only affect the joined table.
SELECT Projects.*,
UserLicenses.*
FROM Projects
LEFT JOIN UserLicenses
ON Projects.id = UserLicenses.project_id
and UserLicenses.user_id = 12
and UserLicences.Question = '6*7'
and UserLicences.Answer = 42
ORDER BY name ASC
This will return projects without matching licenses.
Move the UserLicenses condition away from WHERE, and up to the JOIN condition. By having it in the WHERE part, you will never see those "left" rows because they are filtered away.
You can also probably use WHERE (UserLicenses.user_id = 12 OR UserLicenses.user_id IS NULL)
Don't do that. Just move it to the join condition like this:
LEFT JOIN UserLicenses ON
(Projects.id = UserLicenses.project_id AND UserLicenses.user_id = 12)
You can use LEFT JOIN
If its conditions match then values show otherwise null value shows.