I want to retrieve data from 4 tables. Patient table has id as PK which is the foreign key in other three tables ett, phar and ssc. Where a patient lie in only one category. i.e patient id pt1 exists in either of the 3 tables. now I want to retrieve patient info along with its associated category.
My query is:
SELECT *
FROM Patient p
INNER JOIN ETT t
ON p.Patient_ID = t.Patient_ID || INNER JOIN Pharmacological ph
ON p.Patient_ID = ph.Patient_ID
I used OR clause because I want only 1 inner join executing at one time. but its not giving me results, any suggestions??
....Patient table has ID as PK which is the foreign key in other three
tables name: ett, phar and ssc where a patient lie in only one
category. Example, patient id pt1 exists in either of the 3 tables.
Based on your statement, you can join all the tables in table Patient using LEFT JOIN since a record can only exist on one table. The query below uses COALESCE which returns the first non-null value with int the list.
The only thing you need is to manually specify the column names that you want to be shown on the list as shown below.
SELECT a.*,
COALESCE(t.colA, p.ColA, s.ColA) ColA,
COALESCE(t.colB, p.ColB, s.ColB) ColB,
COALESCE(t.colN, p.ColN, s.ColN) ColN
FROM Patient a
LEFT JOIN ETT t
ON a.Patient_ID = t.Patient_ID
LEFT JOIN Phar p
ON a.Patient_ID = p.Patient_ID
LEFT JOIN SSC s
ON a.Patient_ID = s.Patient_ID
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
For or - do not ise ||, use "or"
You cannot join with or, you need re-format your query.
Related
As the title indicates (in an incorrect way), I would like to create a table bringing together all the lines of 3 different tables, with as common points, their creation date and a folder id (present in each of the 3 tables).
simple schema of the DB : image of the DB schema with relations
How would you write this in SQL ?
PS: it's maybe super easy but I'm all new with SQL, sorry !
PS2: don't hesitate if you need more explanations or precisions
Thank you :)
What I tried :
SELECT product_folder.id AS product_folder_id
pens.brand AS pen_brand
schoolbags.size AS schoolbag_size
notebooks.number_of_pages AS notebook_pages
created_at,
updated_at
FROM product_folders pf
LEFT JOIN product_folders pf ON schoolbags.product_folder_id = pf.id
LEFT JOIN product_folders pf ON pens.product_folder_id = pf.id
LEFT JOIN product_folders pf ON notebooks.product_folder_id = pf.id
But it doesn’t return what I ask (an error).
EDIT :
The error :
'ERROR: table name "pf" specified more than once'
The table should look something like this : image of the table I want to have
More precisely : (*p_f_id = product_folder_id)
------------------------------all-products------------------------------
id p_f_id* brand size price nb_of_pages created_at updated_at
-- ------- ---------- ------- ------ ------------ ----------- ---------
1 34 Watermark NULL 34.00 NULL 12-04-2022 15-04-2022
2 22 NULL medium 40.00 NULL 28-11-2022 29-11-2022
3 18 NULL NULL 12.00 42 06-09-2022 06-09-2022
I know some of the columns will return NULL (ex: pens don't have pages so > NULL) and I'm ok with that.
I just want the column product_folder_id filled with the id of the folder of the different products and the created_at and updated_at columns filled with the date of each rows.
Your first error is that you joined multiple times the table product_folder with the same alias "pf", you cannot do this because if you want to select fields from any of the joined tables, SQL must know which one you want to select from (that's the goal of an alias). You could for example do:
SELECT pf1.id, pf2.id
FROM product_folders pf1
LEFT JOIN product_folders pf2 ON pf2.id = pf1.id
It makes no real sense (it will select twice the same id for each row of product_folders) but shows you that you must use the aliases in the SELECT part and in the ON part to distinguish joined tables.
Your main error though is for your case, you don't need to join on the same table, and then you don't need to give aliases. You want to join directly on the tables you want to select the fields from:
SELECT product_folder.id AS product_folder_id
pens.brand AS pen_brand
schoolbags.size AS schoolbag_size
notebooks.number_of_pages AS notebook_pages
/*created_at,
updated_at*/
FROM product_folders
LEFT JOIN schoolbags ON schoolbags.product_folder_id = product_folders.id
LEFT JOIN pens ON pens.product_folder_id = product_folders.id
LEFT JOIN notebooks ON notebooks.product_folder_id = product_folders.id
I commented created_at, updated_at because from the question we cannot know where you want these columns from, as they don't exist in product_folder. It could be schoolbags.created_at, schoolbags.updated_at or pens.created_at, pens.updated_at or notebooks.created_at, notebooks.updated_at, or all of them...
EDIT FOLLOWING MORE INFOS:
Since you have entries in product_folder that don't correspond to the 3 joined tables, you must filter relevant results with a WHERE.
Additionnally, if each row in product_folder corresponds to only one of the 3 joined tables, you can retreive created_at / updated_at by testing if the id is null (or another field) with IF.
That would give:
SELECT product_folder.id AS product_folder_id,
pens.brand AS pen_brand,
schoolbags.size AS schoolbag_size,
notebooks.number_of_pages AS notebook_pages,
IF(pens.id IS NOT NULL, pens.created_at,
IF(schoolbags.id IS NOT NULL, schoolbags.created_at, notebooks.created_at)
) as created_at,
IF(pens.id IS NOT NULL, pens.updated_at,
IF(schoolbags.id IS NOT NULL, schoolbags.updated_at, notebooks.updated_at)
) as updated_at,
FROM product_folders
LEFT JOIN schoolbags ON schoolbags.product_folder_id = product_folders.id
LEFT JOIN pens ON pens.product_folder_id = product_folders.id
LEFT JOIN notebooks ON notebooks.product_folder_id = product_folders.id
WHERE (pens.brand IS NOT NULL OR schoolbags.size IS NOT NULL OR notebooks.number_of_pages IS NOT NULL)
It is not known, what result you want. Some correction to your query may be help to next step
SELECT
pf.id AS product_folder_id
,pens.brand AS pen_brand
,schoolbags.size AS schoolbag_size
,notebooks.number_of_pages AS notebook_pages
,pf.created_at
,pf.updated_at
FROM product_folders pf
LEFT JOIN product_folders schoolbags ON schoolbags.product_folder_id = pf.id
LEFT JOIN product_folders pens ON pens.product_folder_id = pf.id
LEFT JOIN product_folders notebooks ON notebooks.product_folder_id = pf.id
May be table product_folders has name all_products, as shown on image. Try this
SELECT
pf.id AS product_folder_id
,pens.brand AS pen_brand
,schoolbags.size AS schoolbag_size
,notebooks.number_of_pages AS notebook_pages
,pf.created_at
,pf.updated_at
FROM all_products pf
LEFT JOIN all_products schoolbags ON schoolbags.product_folder_id = pf.id
LEFT JOIN all_products pens ON pens.product_folder_id = pf.id
LEFT JOIN all_products notebooks ON notebooks.product_folder_id = pf.id
Suppose I have three tables here one of them is a Country table second one is a city table and the third one is a customer table, and I am writing a query here like this
SELECT country.country_name_eng, city.city_name, customer.customer_name
FROM Country
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON customer.city_id = city.id
I want to know here who is the left table of the customer table and who is the left table of the city table as well as who is the right table of the country table and who is the right table of the customer table
'Left' is always the table at the left of the JOIN keyword, no matter if left, right, inner or full outer join, analogously 'right'.
Left and right joins, though, have different semantics:
With a normal (inner) join a data row is only added if there's a matching entry in both tables, e.g. if you JOIN ON l.id = r.id then if l contains an id with value 7 a row for is only added if there's a matching id with value 7 in r as well (and vice versa).
A left (outer) join instead adds a row for id 7 in l even if there's no matching id in r – then the corresponding columns for table r are filled with nulls.
Analogously a right (outer) join, all entries of r are added with nulls for l's columns if no matching entry found.
A full outer join is a combination of left and right outer join, any entry of l and r is used with nulls on either side for the counter part if none exists.
In your concrete query you'd list all countries even if there don't exist any cities – and if they do exist, for each country all of them even if there don't exist any customers there. In the latter case the columns for the customer are all filled with null values, and if no city exists either, additionally all city columns.
I have the following DB structure:
And right now I can't make up a query to get
a creator data, admin data and tech data from item_contacts...
What kind of JOIN I need to use and how?
I think you want 3 joins on item_contacts - one for each column whose data you want to recover:
select
i.*,
cc.data as creator_data,
ca.data as admin_data,
ct.data as tech_data
from items i
inner join item_contacts cc on cc.contact_id = i.creator_id
inner join item_contacts ca on ca.contact_id = i.admin_id
inner join item_contacts ct on ct.contact_id = i.tech_id
I am stuck in my liaison of my 3 tables.
I have a table which is candidates with 3 fields (id_candidate, name_candidate, firstname_candidate)
An other table nammed lessons with 5 fields (id_lesson, price_lesson, date_lesson, fk_candidate, fk_monitor)
I have a table which is monitors with 3 fields (id_monitor, name_monitor, firstname_monitor)
I can join 2 tables (candidates and lessons)
Here is the request
SELECT *
FROM lessons INNER JOIN
candidates
ON lessons.fk_candidate=candidates.id_candidate
ORDER BY id_candidate ASC
But my problem is that. I don't understand how to join 3 tables?
In fact, the name of monitor must appear on the table lessons.
I have tried that
SELECT *
FROM candidates id_candidate INNER JOIN
lessons id_lesson
ON lessons.fk_candidate = candidates.id_candidate INNER JOIN
monitors id_monitor
ON lessons.fk_monitor = monitors.id_monitor;
Presumably, something like this:
SELECT c.*, l.*, m.name_monitor -- list out the columns you want explicitly
FROM candidates c INNER JOIN
lessons l
ON l.fk_candidate = c.id_candidate INNER JOIN
monitors m
ON l.fk_monitor = m.id_monitor;
Notes:
Using table aliases is a good idea. I recommend abbreviations for the table name.
After you have defined the table alias, use them. Your on clauses still referred to the table name.
Explicitly list the columns that you want.
I have problems joining 2 table let say I have a column on the 1st table name nationalitycode(this is number) and it fetches the description(it could be american, chinese etc) depending on the first table nationalitycode. So I tried inner join the table so the first inner join is good and working perfectly.
here is the code:
SELECT person.firstnm, person.middlenm, person.lastnm, refcd.description
FROM person
INNER JOIN refcd
ON person.natcd = refcd.id;
However when I try to join the 2nd column from the 1st table let say the column name is gencd(gendercode its a foreign key) but when I updated the query to inner join 2 column from one table getting the value from one column in the 2nd table I get this error.
"Column ambigously defined" I get this error and I understand this my question is is there anyway to achieve my desired output? I want to join 2 table, specifically joining 2 column on table 1 to 1 column in table 2.
Here is my updated query:
SELECT person.firstnm, person.middlenm, person.lastnm, refcd.description
FROM person
INNER JOIN refcd
ON person.natcd = refcd.id
INNER JOIN refcd
ON person.gencd = refcd.id;
Help is really appreciated.
Your query should be
SELECT person.firstnm, person.middlenm, person.lastnm, refcd.description
FROM person INNER JOIN refcd ON person.natcd = refcd.id
INNER JOIN refcd R2 ON person.gencd = R2.id;