i am trying to implement inner and outer join in single query, i am not sure if i am doing the right way or wrong way, as i am not very good with queries.
So here it goes.
I have these following tables.
hrs_residentials
hrs_residential_utilities
hrs_utilities
hrs_utility_type
hrs_residentials:
ResID, ResType, ResNo - - -
1 2 001 - - -
hrs_residential_utilities:
RUID, UtilityID, ResID, - - - -
NULL NULL NULL
hrs_utilities:
UtilityID, UtilityTypeID, Number, ConsumerNumber, -, -, -
NULL NULL NULL NULL
hrs_utility_type:
UTID, UName, UDescription
1 PESCO PESCO Electric Meter
2 SNGPL Sui Northen Gas Pipe Lines
So i want to show in datatables the data, but what i want that data should show in table for hrs_residentials table, dosent matter if hrs_residential_utilities have data or not.
So i went for Left outer join and i got the result i wanted.
But after that when i tried to do inner for hrs_residential_utilities with hrs_utilities, i stopped getting results for hrs_residentials as well. As if we see hrs_residential do have the data inside table. I dont want inner join with hrs_residentials, i want to have inner join between hrs_residential_utilities and hrs_utilities.
Is it possible, or i am following the wrong approach here? Sorry i am not good. What will the Proper Query if anyone can help me with it.
This is the Query i have tried so far.
SELECT R.`ResID`,R.`ResNo`
FROM `hrs_residentials` R
LEFT OUTER JOIN `hrs_residential_utilities` RU
ON R.`ResID` = RU.ResID
INNER JOIN `hrs_utilities` U
ON RU.`UtilityID` = U.`UtilityID`
WHERE 1=1;
I stopped Getting Results from the hrs_residentials table After the Inner Join, but i am making Inner join between other two tables.
Try a subquery like this:
SELECT *
FROM `hrs_residentials` R
LEFT OUTER JOIN
(
SELECT * FROM
`hrs_residential_utilities` RU
INNER JOIN `hrs_utilities` U
ON RU.`UtilityID` = U.`UtilityID`
) AS subqyr
ON R.`ResID` = subqyr.`ResID`
run this query and view the results
SELECT R.ResID,R.ResNo
FROM hrs_residentials R
LEFT OUTER JOIN hrs_residential_utilities RU
ON R.ResID = RU.ResID
then run this query and view the results:
SELECT * FROM hrs_utilities
I suspect what you will find is that the RU.utilities ID does not match anything in the hrs_utilities.
Your query itself should return everything in hrs_residentials and join on any matching data from hrs_residential_utilities this may or may not return RU.ResID as null depending on whether it can match.
It then filters on whether RU.UtilityId matches with anything in the hrs_utilities table, this won't match on null items.
Thanks.
oliver
Related
I'm populating a table which is fetching the ids from 2 other tables to display their information, for example, delivery has a Hamburguer and the box, but the user might register the delivery with out the box, only with the hamburguer.
When I make a INNER JOIN SELECT to get the data from the DB it will return 0 results since there is no box and I'm trying to compare the ids that don't exist. It doesn't populate the table then.
SELECT
entrega_telemovel.*,
telemovel.id_telemovel,
telemovel.nroserie,
nro_telemovel.numero_telemovel,
nro_telemovel.id_nrotelemovel,
funcionarios.id_funcionario,
funcionarios.nome
FROM entrega_telemovel
INNER JOIN telemovel
ON entrega_telemovel.telemovel = telemovel.id_telemovel
INNER JOIN nro_telemovel
ON nro_telemovel.id_nrotelemovel = entrega_telemovel.numero_telemovel
INNER JOIN funcionarios
ON funcionarios.id_funcionario = entrega_telemovel.funcionario_entrega
ORDER BY funcionarios.nome;
In this query above entrega_telemovel.telemovel=telemovel.id_telemovel the value in entrega_telemovel.telemovel is null like the example I gave above. So 0 results are returned from the query.
How can I solve this ?
You are looking for a LEFT JOIN.
INNER JOIN only combines rows, that exist in both tables. A LEFT JOIN on the other hand always produces at least one row. If on table does not have a match for it, all columns are set to NULL.
SELECT
entrega_telemovel.*,
telemovel.id_telemovel,
telemovel.nroserie,
nro_telemovel.numero_telemovel,
nro_telemovel.id_nrotelemovel,
funcionarios.id_funcionario,
funcionarios.nome
FROM entrega_telemovel
LEFT JOIN telemovel
ON entrega_telemovel.telemovel = telemovel.id_telemovel
LEFT JOIN nro_telemovel
ON nro_telemovel.id_nrotelemovel = entrega_telemovel.numero_telemovel
LEFT JOIN funcionarios
ON funcionarios.id_funcionario = entrega_telemovel.funcionario_entrega
ORDER BY funcionarios.nome;
You want to show all entrega_telemovel entries, no matter whether they have a match in entrega_telemovel or not. This is what an outer join does.
SELECT ...
FROM entrega_telemovel et
LEFT OUTER JOIN telemovel t ON et.telemovel = t.id_telemovel
...
Hi dev's i'm new with "advanced" SQL I've try alone but I dont understand how to have the good result.
I'll try to take information from 4 tables in the same DB.
The first table items only have id and name.
2 others tables take the id from items to extract data.
The last tables takes one data from items_buy for print another data.
Lastly I concat 2 column from 2 DB for having a full information.
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
INNER JOIN items_buy ON items_buy.id = items.id)
INNER JOIN trader ON trader.id = items_buy.name_point)
INNER JOIN items_sales ON items_sales.id = items.id)
INNER JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
I dont know how to make it work, she doesnt return an error in SQLyog or on my server.
In order:
ID / NAMEITEM / PRICE / SELLINGPRICE / NAME from concat
If you need more, some test data:
https://pastebin.com/6Bs4kbN9
I've run your test data and run your script against it. As I suggested in my commment, the problem is with the INNER JOIN you are using.
I am not sure whether you are aware, but when using an INNER JOIN, if the joined table is NULL for the current row, then nothing at all will be returned.
If you modify your query to use a LEFT JOIN, you will see the results that are available regardless of whether the joined tables are NULL or otherwise:
SELECT items.id, items.name, items_buy.item_cost AS item_cost, items_sales.item_price AS item_price, CONCAT(trader.name, planet.name) AS name_point
FROM ((((items
LEFT JOIN items_buy ON items_buy.id = items.id)
LEFT JOIN trader ON trader.id = items_buy.name_point)
LEFT JOIN items_sales ON items_sales.id = items.id)
LEFT JOIN planet ON planet.id = trader.planet)
WHERE items.id = 1;
This produces:
1 Agricium 24.45 25.6 NULL
1 Agricium 24.6 25.6 NULL
The problem in the case of your example is that the join to trader or planet has no result and therefore produces no output.
This is my structure of tables:
tables_structure
and there's tbl_owner, tbl_rooms and tbl_class.
How do I get id_class and class name from tbl_class.
The original source code is like this:
SELECT
clas.id_class,
clas.class_name
FROM
tbl_rooms AS room
LEFT JOIN tbl_class AS clas ON room.id_class = clas.id_class
LEFT JOIN tbl_owner AS own ON room.id_owner = own.id_owner
WHERE own.id_owner='1';
However, it did not work. Please help me?
SELECT
clas.id_class,
clas.class_name
FROM
tbl_rooms AS room
LEFT JOIN tbl_class AS clas ON room.id_class = clas.id_class
LEFT JOIN tbl_owner AS own ON room.id_owner = own.id_owner
WHERE own.id_owner='1';
Left Joins and wheres can be a little confusing.
Here you are asking for all rooms and if they have a class return it, it they have an owner return it. Which is done by the left join.
Then after getting that info, Your asking to filter the results by owner = 1
Given that there were left joins used to build this data, you have now said only show the results where both joins matched. Effectively turning the left join to an inner join.
I would take away the where clause and check the join conditions are producing results you expect first, then start to allow the where to narrow the result set.
The correct way to check if a left join is a condition is (own.id_owner='1') OR (own.id_owner is null)
That will bring back all owner = 1 and all unknown owners
When I use right join I get the same results as using left join or just join. Can anyone show me where I have gone wrong?
I have 3 tables as follows:
langugages
id
code eg "hu","en"
language_default
id
text
language_translations
id
lang_id (FK the id of the language in the languages table)
default_lang_id (FK the id of the text in the languages_default table)
text (the translation)
When I execute the following query, I expect to get all of the hungarian translations from the language_translations table and all of the text fields from the language_default table with a null value where there is no hungarian translation.
SELECT `language_translations`.`text`
, `language_default`.`text`
FROM `languages`
, `language_translations`
RIGHT JOIN `language_default` ON `language_default`.`id` = `language_translations`.`default_lang_id`
WHERE `languages`.`code` = 'hu'
AND `languages`.`id` = `language_translations`.`lang_id`
Instead I only get text from the language_default table where there are translations for that text in the tranlsation table. I would expect that behaviour from a left join or normal join but not a right join. Any ideas why I am not getting all of the entries from the langugage_defailt table?
First of all you are using combination of normal join and rights join in wrong way. You can use as per below query.
2nd thing right join means you will get all record from right side and corresponding records from left side and if left side does not have corresponding record then it will show NULL.
Left join is its reverse.
Normal join or comma join will provide only common rows.
So if your tables only have common rows then all joins will provide same results.
SELECT
`language_translations`.`text` , `language_default`.`text`
FROM `languages` AS l
JOIN `language_translations` AS t
ON l.`id` = t.`lang_id` AND l.`code` = 'hu'
RIGHT JOIN `language_default` AS d
ON d.`id` = t.`default_lang_id`;
Don't mix implicit joins and explicit joins. A simple rule is: don't use , in the from clause. The following restructures your query to use left outer join:
SELECT `language_translations`.`text`, ld.`text`
FROM language_default ld left outer join
language_translations lt
on ld.`id` = lt.`default_lang_id` left outer join
`languages` l
on l.`id` = lt.`lang_id` and l.`code` = 'hu' ;
When using outer joins, you need to be very careful about where additional conditions go. Conditions on the driving table (the first a left outer join, the last for a right outer join) can go in the where clause. For other tables, the conditions should go in the on clause. Otherwise, they turn the outer join into an inner for the simple reason that (almost) any comparison to NULL is equivalent to false.
I have this query:
SELECT
TA.id,
T.duration,
DATE_FORMAT(TA.startTime,'%H:%i') AS startTime,
TEI.displayname,
TA.threatment_id,
TE.employeeid,
TTS.appointment_date
FROM
tblEmployee AS TE
INNER Join tblEmployeeInfo AS TEI ON TEI.employeeinfoid = TE.employeeinfoid
LEFT OUTER Join tblAppointment AS TA ON TE.employeeid = TA.employee_id
LEFT OUTER Join tblThreatment AS T ON TA.threatment_id = T.threatmentid
LEFT OUTER Join tblAppointments AS TTS ON TTS.id = TA.appointments_id
AND TTS.appointment_date = '2009-10-19'
LEFT OUTER Join tblCustomerCard AS TCC ON TCC.customercardid = TTS.customercard_id
WHERE
TE.employeeid = 1
What I try to accomplish is to select an employee, if available, all appointments at a given date. When there aren't any appointments, it should at least give the information about the employee.
But right now, it just gives all appointments related to an employee, and passes null when the date doesn't match. Whats going wrong here?
Because you are doing a left OUTER join, it will only join those records that match the On condition and will attach Null when the condition is not met.
You will still get records for which there is no Appointments on that date.
If you did an INNER join, then if the On condition is not met, no record will be output. So you will not get any records for which there are no appointments on that date.
Ok, not sure what database you are on, but this would work on SQL server :
select * from tblEmployee TA
...
left join
( select * from tblAppointments ed where ed.appointment_date = '10/01/2008' ) TTS
on ON TTS.id = TA.appointments_id
Thats the vibe anyway! You might need to tinker a bit.. Im at work and cant get the whole thing going for ya! :)