Not able to LEFT OUTER JOIN three tables - abap

I've got a problem.
Currently I have three tables, the first table is the main table and if there is no record in the second table, write it too. But if a record exists in the second table, so from the third table display "dispo" information..
I want to use three SAP table - lagp, lqua and marc.
Me goal is write all stock positions from lagp.
2x LEFT JOIN doesnt work: "Unable to compare with"B~MATNR". A table can be joined with a maximum of one other table usign LEFT OUTER JOIN.
Structure:
TYPES:
BEGIN OF t_work,
lgnum TYPE lgnum,
lgtyp TYPE lgtyp,
lgpla TYPE lgpla,
bdatu TYPE lagp_bdatu,
matnr TYPE matnr,
verme TYPE lqua_verme,
meins TYPE meins,
dispo TYPE dispo,
END OF t_work.
DATA:
lt_work TYPE TABLE OF t_work INITIAL SIZE 0,
ls_work LIKE LINE OF lt_work.
And SQL command:
SELECT a~lgnum a~lgtyp a~lgpla a~bdatu b~matnr b~verme b~meins c~dispo FROM lagp AS a
LEFT JOIN lqua AS b ON a~lgnum = b~lgnum AND a~lgtyp = b~lgtyp AND a~lgpla = b~lgpla
INNER JOIN marc AS c ON b~matnr = c~matnr AND b~werks = c~werks
INTO TABLE lt_work
WHERE a~lgnum IN so_lgnum
AND a~lgtyp IN so_lgtyp
AND a~skzua EQ space
AND a~skzue EQ space.
But as result is only one stock position - http://i.stack.imgur.com/1sEEo.png
Can you tell me, how the SQL code has look?
Thank you

Try:
SELECT a~lgnum, a~lgtyp, a~lgpla, a~bdatu, b~matnr, b~verme, b~meins, c~dispo
FROM lagp AS a
LEFT JOIN ( lqua AS b
JOIN marc AS c ON b~matnr = c~matnr AND b~werks = c~werks )
ON a~lgnum = b~lgnum AND a~lgtyp = b~lgtyp AND a~lgpla = b~lgpla
INTO TABLE #lt_work
WHERE a~lgnum IN #so_lgnum
AND a~lgtyp IN #so_lgtyp
AND a~skzua EQ #space
AND a~skzue EQ #space.
Other option would be to put the join between LQUA and MARC in a view and do an outer join with the view. Or split out the select on MARC and do that while looping at the data found with a select on LAGP and LQUA.

I got that fine working code:
SELECT ma~matnr ma~mtart ma~ernam ma~ersda ma~laeda
de~maktx as maktx_de fr~maktx as maktx_fr it~maktx as maktx_it
FROM mara as ma
LEFT JOIN MAKT as de ON de~matnr = ma~matnr AND de~spras = 'DE'
LEFT JOIN MAKT as fr ON fr~matnr = ma~matnr AND fr~spras = 'FR'
LEFT JOIN MAKT as it ON it~matnr = ma~matnr AND it~spras = 'IT'
INTO CORRESPONDING FIELDS OF TABLE g_it_material
WHERE ma~ernam IN so_ERNAM
AND ma~laeda IN so_LAEDA
AND ma~matnr IN so_MATNR.
and it works fine. What did you say about multi-leftjoins?

Related

How to join a same table with two tables?

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

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]

What kind of query do I need?

I have a table called physical_exam_tool_and_body_parts that has:
id physical_exam_tool_id body_part_id
the body_parts table has: name_tid
the physical_exam_tools table has: name_tid
The translation table looks like:
id lang text
I'm trying to query:
SELECT physical_exam_tool_text,
body_part_text
FROM physical_exam_tool_and_body_parts
WHERE translation.lang = 'fr'
I want the names of the body part and physical exam tool for the lang 'fr'. How can I do this. I'm new to joins.
body_parts and physical_exam_tools tables have:
id name_tid
name_tid is the id in the translation table. The translation table has id lang text. So the primary key for translations is a composite key (id,lang).
In physical_exam_body_part_and_tool the id's in that are just the ids (foreign keys) for the body_parts and physical_exam_tools table.
Join to the Translation Table twice where lang = 'fr'.
SELECT t.[text] AS [ExamTool], t2.[text] AS [BodyPart]
FROM physical_exam_tool_and_body_parts as p
inner join physical_exam_tool as pet
on p.physical_exam_tool_id = pet.physical_exam_tool_id
and t.lang = 'fr'
inner join translation as t
on pet.name_tid = t.id
inner join body_parts as b
on p.body_part_id = b.body_part_id
inner join translation as t2
on b.name_tid = t2.id
and t2.lang = 'fr'
Something like this.
SELECT PHYSICAL_EXAM_TOOL_TEXT,
BODY_PART_TEXT
FROM PHYSICAL_EXAM_TOOL_AND_BODY_PARTS A
INNER JOIN BODY_PARTS B
ON A.BODY_PART_ID = B.ID
INNER JOIN TRANSLATION C
ON C.ID = B.NAME_TID
WHERE C.LANG = 'FR'

SQL join 3 table

i m using SQL 2008 R2
i got duplicate value from my join table:
SELECT *
FROM LETTRE_VOIT
LEFT JOIN FAWEB_CLIENT ON FAWEB_CLIENT.CODE_CLIENT = LETTRE_VOIT.CODE_CLIENT
LEFT JOIN ORDRE ON ORDRE.CODE_DEST = LETTRE_VOIT.CODE_DEST AND ORDRE.CODE_CLIENT = LETTRE_VOIT.CODE_CLIENT
AND ORDRE.DATE_CLOTUR = LETTRE_VOIT.DATE_CLOTURE
WHERE LETTRE_VOIT.NO_ORDRE IN ('5530','5533')
as you can see on image i got double value of 5530 and 5533.
my table FAWEB_CLIENT with ID Code_Client
table LETTRE_VOIT with ID NOID and NO_ORDRE
table ORDRE with ID NO_ORDRE and NO_CLIENT
i can not use DISTINCT:
error message: The text data type can not be selected as DISTINCT because it is not comparable
I suspect the problem is that your joins are not correct. My suspicion is that you are missing a join condition on Letter_Voit.No_Ordre:
SELECT *
FROM LETTRE_VOIT
LEFT JOIN FAWEB_CLIENT ON FAWEB_CLIENT.CODE_CLIENT = LETTRE_VOIT.CODE_CLIENT
LEFT JOIN ORDRE ON ORDRE.CODE_DEST = LETTRE_VOIT.CODE_DEST AND ORDRE.CODE_CLIENT = LETTRE_VOIT.CODE_CLIENT
AND ORDRE.DATE_CLOTUR = LETTRE_VOIT.DATE_CLOTURE and
LETTRE_VOIT.No_ORDRE = Order.No_ORDRE
WHERE LETTRE_VOIT.NO_ORDRE IN ('5530','5533')
You may be able to remove some of the other join conditions, which may become redundant.

SQL joins "going up" two tables

I'm trying to create a moderately complex query with joins:
SELECT `history`.`id`,
`parts`.`type_id`,
`serialized_parts`.`serial`,
`history_actions`.`action`,
`history`.`date_added`
FROM `history_actions`, `history`
LEFT OUTER JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT OUTER JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
WHERE `history_actions`.`id` = `history`.`action_id`
AND `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
I'd like to replace `parts`.`type_id` in the SELECT statement with `part_list`.`name` where the relationship I need to enforce between the two tables is `part_list`.`id` = `parts`.`type_id`. Also I have to use joins because in some cases `history`.`part_id` may be NULL which obviously isn't a valid part id. How would I modify the query to do this?
Here is some sample date as requested:
history table:
(source: ianburris.com)
serialized_parts table:
(source: ianburris.com)
parts table:
(source: ianburris.com)
part_list table:
(source: ianburris.com)
And what I want to see is:
id name serial action date_added
4 Battery 567 added 2010-05-19 10:42:51
3 Antenna Board 345 added 2010-05-19 10:42:51
2 Main Board 123 added 2010-05-19 10:42:51
1 NULL NULL created 2010-05-19 10:42:51
This would at least be on the right track...
If you're looking to NOT show any parts with an invalid ID, simply change the LEFT JOINs to INNER JOINs (they will restrict NULL values)
SELECT `history`.`id`
, `parts`.`type_id`
, `part_list`.`name`
, `serialized_parts`.`serial`
, `history_actions`.`action`
, `history`.`date_added`
FROM `history_actions`
INNER JOIN `history` ON `history`.`action_id` = `history_actions`.`id`
LEFT JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
LEFT JOIN `part_list` ON `part_list`.`id` = `parts`.`type_id`
WHERE `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
Boy, these backticks make my eyes hurt.
SELECT
h.id,
p.type_id,
pl.name,
sp.serial,
ha.action,
h.date_added
FROM
history h
INNER JOIN history_actions ha ON ha.id = h.action_id
LEFT JOIN parts p ON p.id = h.part_id
LEFT JOIN serialized_parts sp ON sp.parts_id = h.part_id
LEFT JOIN part_list pl ON pl.id = p.type_id
WHERE
h.unit_id = '1'
ORDER BY
history.id DESC