How to join a same table with two tables? - sql

I want to create an Oracle database view :
create or replace force view view_ind_pta (indi_code, nat_indi_code, indi_unite, indi_symbole, indi_lib, indi_cible, pta_intitule, indi_resp,
indi_source_info, user_code, peri_mes_code, peri_mes_lib, pta_parent, deleted,obj_intitule,pta_action)
as
select distinct
i.indi_code,
i.nat_indi_code,
i.indi_unite,
i.indi_symbole,
to_char(i.indi_lib) as indi_lib,
i.indi_cible,
concat(concat(to_char(a.pta_ref),' - '),to_char(a.pta_intitule)) as pta_intitule,
i.indi_resp,
to_char(i.indi_source_info) as indi_source_info,
u.user_code,
i.peri_mes_code ,
pm.peri_mes_lib ,
concat(concat(to_char(p.pta_ref),' - '),to_char(p.pta_intitule)) as pta_parent,
i.deleted ,
to_char(o.obj_intitule) as obj_intitule,
concat(concat(to_char(action.pta_ref),' - '),to_char(action.pta_intitule)) as pta_action
from
indicateur i
left join acteur_saisie_indicateur ai on ai.indi_code = i.indi_code
left join acteur_verif_indicateur avi on avi.indi_code = i.indi_code
left join utilisateur u on ( ai.user_code = u.user_code and avi.user_code = u.user_code)
left join objectif o on i.obj_code = o.obj_code
left join pta a on o.pta_code = a.pta_code
left join pta action on a.pta_pta_code = action.pta_code
left join pta p on action.pta_pta_code = p.pta_code
left join periodicite_mesure pm on pm.peri_mes_code = i.peri_mes_code
where p.pta_definitif = 3;
In the view there is the table utilisateur which I want to join with the two tables acteur_saisie_indicateur and acteur_verif_indicateur. I tried the and operator , but I think it is not a good idea because the query will return rows only when there are joined rows in both tables ! Although this is not necessary : I want the query to return rows even if only one table has joined rows. So how to join these three tables ?

We can include the same table in a FROM clause more than once. All we need to do is use different aliases to distinguish the instances:
left join utilisateur uai
on ai.user_code = uai.user_code
left join utilisateur uavi
on avi.user_code = uavi.user_code
The other thing you need to do is handle table's columns in the view's projection. You want to display the utilisateur values regardless of which instance the values come from, say by using nvl() or the industry standard coalesce()
coalesce(uai.user_code, uavi.user_code) as user_code

You need to join the table twice:
left join acteur_saisie_indicateur ai on ai.indi_code = i.indi_code
left join acteur_verif_indicateur avi on avi.indi_code = i.indi_code
left join utilisateur u on ai.user_code = u.user_code
left join utilisateur u2 on avi.user_code = u2.user_code

Related

Passing different column values to where clause

SELECT pims.icicimedicalexaminerreport.id,
pims.icicimerfemaleapplicant.adversemenstrualid,
pims.icicimerfemaleapplicant.pregnantid,
pims.icicimerfemaleapplicant.miscarriageabortionid,
pims.icicimerfemaleapplicant.breastdiseaseid,
pims.pimscase.tiannumber
FROM pims.pimscase
INNER JOIN pims.digitization
ON pims.pimscase.digitizationid = pims.digitization.id
INNER JOIN pims.medicalexaminerreport
ON pims.digitization.medicalexaminerreportid =
pims.medicalexaminerreport.id
INNER JOIN pims.icicimedicalexaminerreport
ON pims.medicalexaminerreport.id =
pims.icicimedicalexaminerreport.id
INNER JOIN pims.icicimerfemaleapplicant
ON pims.icicimedicalexaminerreport.id =
pims.icicimerfemaleapplicant.id
WHERE pims.pimscase.tiannumber = 'ICICI1234567890'
which gives me the following output
Now I want to use the above output values to select the rows from the table "YesNoAnswerWithObservation"
I imagine it should look something like this Select * from YesNoAnswerWithObservation Where Id in (22,27,26,...23)
Only instead of typing the values inside IN clause I want to use the values in each column resulting from above-mentioned query.
I tried the below code but it returns all the rows in the table rather than rows mentioned inside the In
SELECT pims.yesnoanswerwithobservation.observation,
graphitegtccore.yesnoquestion.description,
pims.yesnoanswerwithobservation.id ObservationId
FROM pims.yesnoanswerwithobservation
INNER JOIN graphitegtccore.yesnoquestion
ON pims.yesnoanswerwithobservation.yesnoanswerid =
graphitegtccore.yesnoquestion.id
WHERE EXISTS (SELECT pims.icicimedicalexaminerreport.id,
pims.icicimerfemaleapplicant.adversemenstrualid,
pims.icicimerfemaleapplicant.pregnantid,
pims.icicimerfemaleapplicant.pelvicorgandiseaseid,
pims.icicimerfemaleapplicant.miscarriageabortionid,
pims.icicimerfemaleapplicant.gynocologicalscanid,
pims.icicimerfemaleapplicant.breastdiseaseid,
pims.pimscase.tiannumber
FROM pims.pimscase
INNER JOIN pims.digitization
ON pims.pimscase.digitizationid =
pims.digitization.id
INNER JOIN pims.medicalexaminerreport
ON pims.digitization.medicalexaminerreportid =
pims.medicalexaminerreport.id
INNER JOIN pims.icicimedicalexaminerreport
ON pims.medicalexaminerreport.id =
pims.icicimedicalexaminerreport.id
INNER JOIN pims.icicimerfemaleapplicant
ON pims.icicimedicalexaminerreport.id =
pims.icicimerfemaleapplicant.id
WHERE pims.pimscase.tiannumber = 'ICICI1234567890')
Any help or a nudge in the right direction would be greatly appreciated
Presumably you want the ids from the first query:
SELECT awo.observation, ynq.description, ynq.id as ObservationId
FROM pims.yesnoanswerwithobservation awo JOIN
graphitegtccore.yesnoquestion ynq
ON awo.yesnoanswerid = ynq.id
WHERE ynq.id = (SELECT mer.id
FROM pims.pimscase c JOIN
pims.digitization d
ON c.digitizationid = d.id JOIN
pims.medicalexaminerreport mer
ON d.medicalexaminerreportid = mer.id JOIN
pims.icicimedicalexaminerreport imer
ON mer.id = imer.id JOIN
pims.icicimerfemaleapplicant ifa
ON imer.id = ifa.id
WHERE c.tiannumber = 'ICICI1234567890'
) ;
Notice that table aliases make the query much easier to write and to read.

Inner join multiple ID columns with ID in foreign table to display multiple name columns

I need to make a query that inner joins 3 different id's from one table with the id from another, to then display the name value from that table in my select query. I'll try to make it a bit more clear.
In my one table I have these 3 columns with id's:
Book_Kalender.BS_ID,
Book_Kalender.BS_ID_Prio2,
Book_Kalender.BS_ID_Prio3,
These all need to be inner joined with a column in another table, which contains the name associated with these ids:
Book_Sommerhuse.[BS_ID]
In my SELECT query I am including the name column from the foreign table. I want to instead have 3 columns, each with the associated name that corresponds to the ID.
Book_Sommerhuse.BS_Navn
So far I have tried to make multiple inner joins using the AND keyword:
INNER JOIN Book_Kalender ON Book_Sommerhuse.[BS_ID] = Book_Kalender.[BS_ID]
AND Book_Sommerhuse.[BS_ID] = Book_Kalender.[BS_ID_Prio2]
But this returns and empty view from my select query. I'm also not sure how to create new columns for each name associated with the ID.
Full query:
SELECT
Book_Kalender.BK_ID,
Book_Kalender.BK_DatoFra,
Book_Kalender.BK_DatoTil,
Book_Kalender.BK_M_Navn,
Book_Kalender.BK_M_Adr,
Book_Kalender.BK_M_PostBy,
Book_Kalender.BK_M_Afd,
Book_Kalender.BK_M_MedArbNr,
Book_Kalender.BK_M_Tlf,
Book_Kalender.BK_M_Email,
Book_Kalender.BK_Tidl_Lejet,
Book_Kalender.BK_Tidl_Lejet_Txt,
Book_Kalender.BS_ID,
Book_Kalender.BS_ID_Prio2,
Book_Kalender.BS_ID_Prio3,
A.BS_Navn as BS_Navn1,
B.BS_Navn as BS_Navn2,
c.BS_Navn as BS_Navn3,
coalesce(A.BS_Navn,B.BS_Navn,c.BS_Navn) as BS_Navn
FROM
Book_Kalender
LEFT JOIN Book_Sommerhuse A ON
Book_Kalender.BS_ID = A.BS_ID
LEFT JOIN Book_Sommerhuse B ON
Book_Kalender.BS_ID_Prio2 = B.BS_ID
LEFT JOIN Book_Sommerhuse C ON
Book_Kalender.BS_ID_Prio3 = C.BS_ID
WHERE
Book_Kalender.BK_DatoFra BETWEEN #10/15/2017# AND #12/31/2018#;
You need 3 left join :
select
Book_Kalender.*,
A.BS_Navn as BS_Navn1,
B.BS_Navn as BS_Navn2,
C.BS_Navn as BS_Navn3,
coalesce(A.BS_Navn,B.BS_Navn,c.BS_Navn) as BS_Navn -- first non null BS_Navn
from
Book_Kalender
LEFT JOIN Book_Sommerhuse A ON
Book_Kalender.BS_ID = A.BS_ID
LEFT JOIN Book_Sommerhuse B ON
Book_Kalender.BS_ID_Prio2 = B.BS_ID
LEFT JOIN Book_Sommerhuse C ON
Book_Kalender.BS_ID_Prio3 = C.BS_ID
SELECT
K.BS_ID
,S1.BS_Navn
,K.BS_ID_Prio2
,S2.BS_Navn 'Prio2_BS_Navn'
,K.BS_ID_Prio3
,S3.BS_Navn 'Prio3_BS_Navn'
FROM
Book_Kalender K
LEFT JOIN
Book_Sommerhuse S1 ON S1.BS_ID = K.BS_ID
LEFT JOIN
Book_Sommerhuse S2 ON S2.BS_ID = K.BS_ID_Prio2
LEFT JOIN
Book_Sommerhuse S3 ON S3.BS_ID = K.BS_ID_Prio3
Use could use derived table which could provide you three columns data as a single column and then you could apply the join , something like this
INNER JOIN (
SELECT BS_IDs FROM Book_Kalender CROSS APPLY(
VALUES (BS_ID), (BS_ID_Prio2), (BS_ID_Prio3)) Cols(BS_IDs)
) DerivedBook_Kalender ON Book_Sommerhuse.[BS_ID] = DerivedBook_Kalender.[BS_IDs]

Postgresql - Conditional Join if data exist

My current query show the data from the table called "Buque" and has some references from another tables. The problem is when i execute the query it never shows the result because it consumes too much memory i guess.
The current query i have
select buq.buq_codigo, tbu.tbu_codigo, tbu.tbu_nombre, pai.pai_codigo, pai.pai_nombre,
pue.pto_codigo, pue.pto_nombre, lin.lin_codigo, lin.lin_nombre, tra.tra_codigo,
tra.tra_nombre, buq.buq_nombre, buq.buq_des, buq.num_trb, buq.num_eslora,
buq.max_tons, buq.reg_lloyd, buq.buq_codigo1, buq.codigo_omi,
case buq.buq_estado when 'A' then 'Activo' else 'Inactivo' end as buq_estado
from publico.mae_buque as buq, publico.mae_tipbuque as tbu, publico.mae_pais as pai,
publico.mae_puerto as pue, publico.mae_linea as lin, publico.mae_trafico as tra
where buq.tbu_codigo = tbu.tbu_codigo or
buq.pai_codigo = pai.pai_codigo or
buq.pto_codigo = pue.pto_codigo or
buq.lin_codigo = lin.lin_codigo or
buq.tra_codigo = tra.tra_codigo
I also tried with inner joins but the problem is it returns me the data that meets the conditions of the joins. In other words, if the join has data to compare, returns the name, if not, show the null data.
The query must return me 611 records, with inner joins returns 68 records.
Concerning your desired result, use left outer joins, which fill up any non-existing rows of the right hand side table with null-values;
Concerning the out of memory issue, note that you used or to connect your tables; this actually leads to the fact that almost every record of the involved tables is connected to almost every other record (almost a cross join / cartesian product); This can get very large if you connect 6 tables...
select buq.buq_codigo, tbu.tbu_codigo, tbu.tbu_nombre, pai.pai_codigo, pai.pai_nombre,
pue.pto_codigo, pue.pto_nombre, lin.lin_codigo, lin.lin_nombre, tra.tra_codigo,
tra.tra_nombre, buq.buq_nombre, buq.buq_des, buq.num_trb, buq.num_eslora,
buq.max_tons, buq.reg_lloyd, buq.buq_codigo1, buq.codigo_omi,
case buq.buq_estado when 'A' then 'Activo' else 'Inactivo' end as buq_estado
from publico.mae_buque as buq
left outer join publico.mae_tipbuque as tbu on buq.tbu_codigo = tbu.tbu_codigo
left outer join publico.mae_pais as pai on (buq.pai_codigo = pai.pai_codigo)
left outer join publico.mae_puerto as pue on (buq.pto_codigo = pue.pto_codigo)
left outer join publico.mae_linea as lin on (buq.lin_codigo = lin.lin_codigo)
left outer join publico.mae_trafico as tra on (buq.tra_codigo = tra.tra_codigo)
You have to use left outer join:
select *
from
publico.mae_buque as buq
left outer join publico.mae_tipbuque as tbu on (buq.tbu_codigo = tbu.tbu_codigo)
left outer join publico.mae_pais as pai on (buq.pai_codigo = pai.pai_codigo)
left outer join publico.mae_puerto as pue on (buq.pto_codigo = pue.pto_codigo )
left outer join publico.mae_linea as lin on (buq.lin_codigo = lin.lin_codigo)
left outer join publico.mae_trafico as tra on (buq.tra_codigo = tra.tra_codigo);

Access left join not working as I am picturing it

I am trying to write a query that involves 3 tables and left joining two of them onto a main one.
SELECT UNIT_MAIN.UNIT_NO, DEPT_MAIN.LEV_2, Card.CardNumberLong AS [Some
Number], Card.Enabled, F_CARD.CARD_NO, F_CARD.END_DT
FROM (((UNIT_MAIN
INNER JOIN DEPT_MAIN ON UNIT_MAIN.USING_DEPT = DEPT_MAIN.DEPT_ID)
LEFT JOIN Card ON (UNIT_MAIN.UNIT_NO = Card.UnitCode AND Card.Enabled = True) )
LEFT JOIN F_CARD ON (UNIT_MAIN.UNIT_ID = F_CARD.ASSIGNED_ID AND (F_CARD.END_DT) Is Null ))
WHERE (((UNIT_MAIN.STATUS)="A") AND ((DEPT_MAIN.LEV_2)="AM") AND ((Card.Enabled)=True) )
OR (((UNIT_MAIN.STATUS)="D") AND ((DEPT_MAIN.LEV_2)="AM") AND ((Card.Enabled)=True) )
The issue I am having is when F_CARD table has rows where the F_CARD.END_DT is not null, causing the main table (unit table) not to show up even though it is a left join and the F_CARD table rows did not satisfy the join condition (or I am to believe).
I don't have any where clauses on the F_CARD table and they are only on the join condition.
edit
When I perform
LEFT JOIN MFIVE_F_CARD ON (MFIVE_UNIT_DEPT_COMP_MAIN.UNIT_ID = MFIVE_F_CARD.ASSIGNED_ID AND ((MFIVE_F_CARD.END_DT) Is Null)
The unit does not appear if the F_CARD table contained rows that had an END_DT, I was to believe that since the left join condition failed, the inner table (unit table) should appear regardless.
If I remove any F_CARD related values from the query, the missing units I am looking for appear. It is an inner join, left join, left join. When the second left join happens, I lose rows even when they should appear.
I narrowed down my joins and just did the inner with the left with F_CARD. Trying to see why it doesnt return rows where the join fails.
Tried to do the following, however im getting an unsupported join error...
SELECT
UNIT_MAIN.UNIT_NO
,DEPT_MAIN.LEV_2
,Card.CardNumberLong AS [SomeNumber]
,Card.Enabled
,F_CARD.CARD_NO
,F_CARD.END_DT FROM
(
(
(
UNIT_MAIN
INNER JOIN DEPT_MAIN
ON UNIT_MAIN.USING_DEPT = DEPT_MAIN.DEPT_ID
)
LEFT JOIN Card
ON (UNIT_MAIN.UNIT_NO = Card.UnitCode AND Card.Enabled = True)
)
LEFT JOIN F_CARD
ON (UNIT_MAIN.UNIT_ID = F_CARD.ASSIGNED_ID AND F_CARD.END_DT Is Null)
) WHERE
(UNIT_MAIN.STATUS = "A" OR UNIT_MAIN.STATUS = "D")
AND DEPT_MAIN.LEV_2 = "AM"
Thanks.
I have a feeling it's because you have clauses in your joins that are doing boolean checks rather than matching records between the tables, i.e.
Card.Enabled = True and (F_CARD.END_DT) IS NULL
Try changing the query to:
SELECT
UNIT_MAIN.UNIT_NO
,DEPT_MAIN.LEV_2
,Card.CardNumberLong AS [SomeNumber]
,Card.Enabled
,F_CARD.CARD_NO
,F_CARD.END_DT
FROM
(
(
(
UNIT_MAIN
INNER JOIN DEPT_MAIN
ON UNIT_MAIN.USING_DEPT = DEPT_MAIN.DEPT_ID
)
LEFT JOIN Card
ON UNIT_MAIN.UNIT_NO = Card.UnitCode
)
LEFT JOIN F_CARD
ON UNIT_MAIN.UNIT_ID = F_CARD.ASSIGNED_ID
)
WHERE
(UNIT_MAIN.STATUS = "A" OR UNIT_MAIN.STATUS = "D")
AND DEPT_MAIN.LEV_2 = "AM"
AND Card.Enabled = True

LEFT JOIN ON COALESCE(a, b, c) - very strange behavior

I have encountered very strange behavior of my query and I wasted a lot of time to understand what causes it, in vane. So I am asking for your help.
SELECT count(*) FROM main_table
LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
LEFT JOIN key_table ON key_table.pk = COALESCE(info_table.fk_key_table, front_table.fk_key_table_1, front_table.fk_key_table_2)
LEFT JOIN side_table ON side_table.fk_front_table = front_table.pk
WHERE side_table.pk = (SELECT MAX(pk) FROM side_table WHERE fk_front_table = front_table.pk)
OR side_table.pk IS NULL
Seems like a simple join query, with coalesce, I've used this technique before(not too many times) and it worked right.
In this query I don't ever get nulls for side_table.pk. If I remove coalesce or just don't use key_table, then the query returns rows with many null side_table.pk, but if I add coalesce join, I can't get those nulls.
It seems key_table and side_table don't have anything in common, but the result is so weird.
Also, when I don't use side_table and WHERE clause, the count(*) result with coalesce and without differs, but I can't see any pattern in rows missing, it seems random!
Real query:
SELECT ECHANGE.EXC_AUTO_KEY, STOCK_RESERVATIONS.STR_AUTO_KEY FROM EXCHANGE
LEFT JOIN WO_BOM ON WO_BOM.WOB_AUTO_KEY = EXCHANGE.WOB_AUTO_KEY
LEFT JOIN VIEW_WO_SUB ON VIEW_WO_SUB.WOO_AUTO_KEY = WO_BOM.WOO_AUTO_KEY
LEFT JOIN STOCK stock3 ON stock3.STM_AUTO_KEY = EXCHANGE.STM_AUTO_KEY
LEFT JOIN STOCK stock2 ON stock2.STM_AUTO_KEY = EXCHANGE.ORIG_STM
LEFT JOIN CONSIGNMENT_CODES con2 ON con2.CNC_AUTO_KEY = stock2.CNC_AUTO_KEY
LEFT JOIN CONSIGNMENT_CODES con3 ON con3.CNC_AUTO_KEY = stock3.CNC_AUTO_KEY
LEFT JOIN CI_UTL ON CI_UTL.CUT_AUTO_KEY = EXCHANGE.CUT_AUTO_KEY
LEFT JOIN PART_CONDITION_CODES pcc2 ON pcc2.PCC_AUTO_KEY = stock2.PCC_AUTO_KEY
LEFT JOIN PART_CONDITION_CODES pcc3 ON pcc3.PCC_AUTO_KEY = stock3.PCC_AUTO_KEY
LEFT JOIN STOCK_RESERVATIONS ON STOCK_RESERVATIONS.STM_AUTO_KEY = stock3.STM_AUTO_KEY
LEFT JOIN WAREHOUSE wh2 ON wh2.WHS_AUTO_KEY = stock2.WHS_ORIGINAL
LEFT JOIN SM_HISTORY ON (SM_HISTORY.STM_AUTO_KEY = EXCHANGE.ORIG_STM AND SM_HISTORY.WOB_REF = EXCHANGE.WOB_AUTO_KEY)
LEFT JOIN RC_DETAIL ON stock3.RCD_AUTO_KEY = RC_DETAIL.RCD_AUTO_KEY
LEFT JOIN RC_HEADER ON RC_HEADER.RCH_AUTO_KEY = RC_DETAIL.RCH_AUTO_KEY
LEFT JOIN WAREHOUSE wh3 ON wh3.WHS_AUTO_KEY = COALESCE(RC_DETAIL.WHS_AUTO_KEY, stock3.WHS_ORIGINAL, stock3.WHS_AUTO_KEY)
WHERE STOCK_RESERVATIONS.STR_AUTO_KEY = (SELECT MAX(STR_AUTO_KEY) FROM STOCK_RESERVATIONS WHERE STM_AUTO_KEY = stock3.STM_AUTO_KEY)
OR STOCK_RESERVATIONS.STR_AUTO_KEY IS NULL
Removing LEFT JOIN WAREHOUSE wh3 gives me about unique EXC_AUTO_KEY values with a lot of NULL STR_AUTO_KEY, while leaving this row removes all NULL STR_AUTO_KEY.
I recreated simple tables with numbers with the same structure and query works without any problems o.0
I have a feeling COALESCE is acting as a REQUIRED flag for the joined table, hence shooting the LEFT JOIN to become an INNER JOIN.
Try this:
SELECT COUNT(*)
FROM main_table
LEFT JOIN front_table ON front_table.pk = main_table.fk_front_table
LEFT JOIN info_table ON info_table.pk = front_table.fk_info_table
LEFT JOIN key_table ON key_table.pk = NVL(info_table.fk_key_table, NVL(front_table.fk_key_table_1, front_table.fk_key_table_2))
LEFT JOIN (SELECT fk_, MAX(pk) as pk FROM side_table GROUP BY fk_) st ON st.fk_ = front_table.pk
NVL might behave just the same though...
I undertood what was the problem (not entirely though): there is a LEFT JOIN VIEW_WO_SUB in original query, 3rd line. It causes this query to act in a weird way.
When I replaced the view with the other table which contained the information I needed, the query started returning right results.
Basically, with this view join, NVL, COALESCE or CASE join with combination of certain arguments did not work along with OR clause in WHERE subquery, all rest was fine. ALthough, I could get the query to work with this view join, by changing the order of joined tables, I had to place table participating in where subquery to the bottom.