DB2 SQL multiple JOIN issue - sql

I have a query with two JOIN and it does not work. I get no errors. It just does not return any records. If I separate my query then it works. What Am I doing wrong here?
When I split up the query I get one record each which is what I should get.
Full query:
SELECT HPOL07.*, #RFC.*, #AAM.*
FROM BPCSPROF.HPOL07
JOIN BPCSPROF.#RFC ON PRFC = #RFC.RFCNUM AND PPRF = #RFC.RFCPRC
AND PGLNO = #RFC.RFCGLN
JOIN BPCSPROF.#AAM ON PPRF = #AAM.AAMPRC AND PGLNO = #AAM.AAMGLN
WHERE PORD = '605400' AND PID <> 'PZ'
Separate queries:
SELECT HPOL07.*, #RFC.*
FROM BPCSPROF.HPOL07
JOIN BPCSPROF.#RFC ON PRFC = #RFC.RFCNUM AND PPRF = #RFC.RFCPRC
AND PGLNO = #RFC.RFCGLN
WHERE PORD = '605400' AND PID <> 'PZ'
SELECT HPOL07.*, #AAM.*
FROM BPCSPROF.HPOL07
JOIN BPCSPROF.#AAM ON PPRF = #AAM.AAMPRC AND PGLNO = #AAM.AAMGLN
WHERE PORD = '605400' AND PID <> 'PZ'

You're doing inner joins, so there must be a record in both #RFC and #AAM for each record in HPOL07...
Is that what you want?
If there's a matching record in #RFC or #AAM, then you'd want to use a LEFT OUTER JOIN
SELECT HPOL07.*, #RFC.*, #AAM.*
FROM BPCSPROF.HPOL07
LEFT OUTER JOIN BPCSPROF.#RFC
ON PRFC = #RFC.RFCNUM AND PPRF = #RFC.RFCPRC
AND PGLNO = #RFC.RFCGLN
LEFT OUTER JOIN BPCSPROF.#AAM
ON PPRF = #AAM.AAMPRC AND PGLNO = #AAM.AAMGLN
WHERE PORD = '605400' AND PID <> 'PZ'

This question could certainly use a table schema but my guess is that PGLNO is a different value between your two joins. If that's the case, the joins aren't going to to work because it is effectively looking for #AAM.AAMGLN = #RFC.RFCGLN in your current query. This is because both joins use the PGLNO value and would need to be the same for both join clauses.
If you want two separate results, #Charles answer should do what you want.

You can also use:
SELECT * FROM A h
LEFT JOIN B pk ON (pk.PKKONZ='010') AND (pk.PKFIRM IN (10, 20 30)) AND h.TPPALN = pk.PKPALN
LEFT JOIN C ar ON (ar.TZKONZ='010') AND (ar.TZFIRM IN (55, 56 ,57)) AND h.TPIDEN = ar.TZIDEN
WHERE ....
ORDER BY ...

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.

Select statement where joins causing records to be excluded

I have the below query with multiple joins.The last 3 joins are required to get the g.fin_id value. This works fine (see results) BUT because some records in the ACCUM_ISS_CHAR_HIST table have e.char9_nme values of NULL, it excludes the records in the results altogether. So it seems as when the e.char9_nme value has a record then it will produce a result, but as soon as it has a Null value then it is excluded. I would still like to see the records even though the g.fin_id for those will then be blank because they have a e.char9_nme value of Null. How can I change the query to accomplish this?
select
a.acct_id,
c.fld3_txt,
b.issue_loc1_cde,
b.instr_id,
a.fld1_nme,
b.issue_cls2_nme,
g.fin_id,
e.char9_nme
from position_dg as a
inner join
infoportal..issue_dg as b on b.INSTR_ID = a.INSTR_ID
inner join
InfoPortal..IVW_ACCT as c on a.acct_id = c.acct_id
inner join
InfoPortal..DW_AcctCharDG as d on a.acct_id = d.acctid
inner join
ACCUM_ISS_CHAR_HIST as e on a.instr_id = e.instr_id
inner join
MD_FINANCIAL_ENTITY as f on e.char9_nme = f.fin_enty_name
inner join md_FINANCIAL_ENTITY_ALTERNATE_IDENTIFIER as g on
f.fin_enty_id = g.fin_enty_id
and b.MAT_EXP_DTE > getdate()
and b.issue_cls1_nme = 'Derivatives'
and a.as_of_tms >= getdate()-1
and b.iss_typ in ('FFX','IRS','EQF')
and d.AcctChrSetId = 'DerivativeRpt'
and d.EndTms IS NULL
and a.acct_id = 'FOGEMBLCR'
and g.id_ctxt_typ = 'LEGAL_ENTITY_IDENTIFIER'
and e.as_of_dte = (
select MAX (as_of_dte)-1
from accum_iss_char_hist
)
I expect the results to show fin_id records for some ond blank fin_id records for some, but at the moment only the ones with a fin_id record is hown and the rest is excluded from the results.
You are looking for a left join.
Join all those tables (last 3 as you said) as left join. For better clarity I have moved conditions of every tables in their ON clause and for base table a made a where clause.
select
a.acct_id,
c.fld3_txt,
b.issue_loc1_cde,
b.instr_id,
a.fld1_nme,
b.issue_cls2_nme,
g.fin_id,
e.char9_nme
from position_dg as a
inner join
infoportal..issue_dg as b on b.INSTR_ID = a.INSTR_ID
and b.MAT_EXP_DTE > getdate()
and b.issue_cls1_nme = 'Derivatives'
and b.iss_typ in ('FFX','IRS','EQF')
inner join
InfoPortal..IVW_ACCT as c on a.acct_id = c.acct_id
inner join
InfoPortal..DW_AcctCharDG as d on a.acct_id = d.acctid
and d.AcctChrSetId = 'DerivativeRpt'
and d.EndTms IS NULL
left join
ACCUM_ISS_CHAR_HIST as e on a.instr_id = e.instr_id
and e.as_of_dte = (
select MAX (as_of_dte)-1
from accum_iss_char_hist
)
left join
MD_FINANCIAL_ENTITY as f on e.char9_nme = f.fin_enty_name
left join
md_FINANCIAL_ENTITY_ALTERNATE_IDENTIFIER as g on f.fin_enty_id = g.fin_enty_id
and g.id_ctxt_typ = 'LEGAL_ENTITY_IDENTIFIER'
Where a.as_of_tms >= getdate()-1
and a.acct_id = 'FOGEMBLCR'

Cannot get both records with SQL/Bigquery JOINs

I've got a query that returns order details, I want information from the briisk table for deals it has found. I also want it to display orders even if the briisk table has nothing.
If I add the final line (and flostream.briisk.master = "") my query only returns one result instead of two.
SELECT *
FROM (SELECT orderno,ifnull(dealid,sales_rule) as DealIDCombo from flostream.orders left join mobileheads.surveys on mobileheads.surveys.order_number = flostream.orders.externalreference) as first
INNER JOIN flostream.orders on first.orderno = flostream.orders.orderno
LEFT JOIN flostream.briisk on first.dealidcombo = flostream.briisk.uniquereference
WHERE first.orderno in (359692,359683)
//AND flostream.briisk.master = ""
When you use a left outer join, then you need to include filter conditions on the second table in the on clause. So try this:
SELECT *
FROM (SELECT orderno,ifnull(dealid,sales_rule) as DealIDCombo
from flostream.orders left join
mobileheads.surveys
on mobileheads.surveys.order_number = flostream.orders.externalreference
) as first INNER JOIN
flostream.orders
on first.orderno = flostream.orders.orderno LEFT JOIN
flostream.briisk
on first.dealidcombo = flostream.briisk.uniquereference AND
flostream.briisk.master = ""
WHERE first.orderno in (359692, 359683)
Conditions on the first table should go in the WHERE clause.

SQL Stored Procedure With One To Many Relationship Return Only Most Recent Record

I've been having a terrible time with this. I created a stored procedure to return a corresponding record, but one of the tables has multiple print jobs so it returns multiple records. I only want the most recent requested print job to return and I can't get it to work correctly.
Please help!
SELECT PrintJobs.WORDERKey,
PrintJobs.JobNumber,
WORDER.U_DateRequired AS DateRequired,
ProductMaster.PartFileItemID,
WORDER.ManufacturingDepartment AS MfgDept,
PrintJobs.Copies AS LabelCopies,
PrintJobs.ExpiryDate AS JobExpiryDate,
PrintJobs.Batch,
PrintJobs.JulianDate AS JobJulianDate,
ProductMaster.Description,
ProductMaster.PackFormat,
ProductMaster.IngDec,
ProductMaster.BarCodeNumber,
ProductMaster.CustomerProductCode,
ProductMaster.CriticalInstruction,
ProductMaster.StorageInstruction,
ProductMaster.MixedCaseTitle,
ProductMaster.MixedCode1,
ProductMaster.MixedCode2,
ProductMaster.MixedCode3,
ProductMaster.MixedCode4,
ProductMaster.MixedDescription1,
ProductMaster.MixedDescription2,
ProductMaster.MixedDescription3,
ProductMaster.MixedDescription4,
ProductMaster.MixedIngDec1,
ProductMaster.MixedIngDec2,
ProductMaster.MixedIngDec3,
ProductMaster.MixedIngDec4,
ProductMaster.CookingInstruction,
ProductMaster.LogoFilename,
ProductMaster.ProductExpiryRule,
ExpiryRulesMaster.GS1_AppID,
ProductMaster.LabelTemplateID,
CASE WHEN ProductMaster.PartFileItemID IS NULL THEN 'N' ELSE 'Y' END AS LabelDefExists,
LabelTemplateMaster.FileName,
CASE WHEN [DateFormat] = 'Default' THEN ExpiryRulesMaster.DateFormatString ELSE [DateFormat] END AS DateFormatString,
ExpiryRulesMaster.DateRounding,
ExpiryRulesMaster.ExcludeXmasNewYear,
PART.ExternalShelfLifeTotalDays,
CustomOptions.Tagline,
CustomOptions.ShortName AS CustShortName,
ExpiryRulesMaster.LabelText AS ExpiryRuleLabelText,
ProductMaster.inner_hDescription,
ProductMaster.inner_vDescription,
ProductMaster.inner_CustCode,
ProductMaster.inner_Storage,
ProductMaster.inner_WarningMsg,
ProductMaster.inner_Dateformat,
ProductMaster.inner_SpecialCode,
ProductMaster.LabelType,
ProductMaster.inner_MicroSuiteCode,
ProductMaster.inner_PackWeight,
ProductMaster.inner_JDateFormat,
ProductMaster.CustomOptionID,
ProductMaster.inner_PrintLogo,
PART.NominalWeight,
ProductMaster.IngDec_html,
ProductMaster.IngDec_Active,
PrintJobs.PrintJobsID,
MaxJobs.MaxJob,
PrintJobs.DateEntered
FROM ProductMaster RIGHT OUTER JOIN
(
SELECT Partfileitemid,
--JobNumber,
MAX(dateentered) MaxJob
FROM PrintJobs
GROUP BY PartFileItemID
)
MaxJobs ON ProductMaster.PartFileItemID = MaxJobs.PartFileItemID RIGHT OUTER JOIN
PrintJobs ON PrintJobs.PartFileItemID = MaxJobs.PartFileItemID RIGHT OUTER JOIN
LabelTemplateMaster ON ProductMaster.LabelTemplateID = LabelTemplateMaster.LabelTemplateID LEFT OUTER JOIN
CustomOptions ON ProductMaster.CustomOptionID = CustomOptions.CustomOptionID LEFT OUTER JOIN
ExpiryRulesMaster ON ProductMaster.ProductExpiryRule = ExpiryRulesMaster.ExpiryRule LEFT OUTER JOIN
[F8Extract].[dbo].[WORDER] ON PrintJobs.WORDERKey = WORDER.WORDERKey LEFT OUTER JOIN
[F8Extract].[dbo].[PART] ON ProductMaster.PartFileItemID = Part.PartFileItemID
WHERE PrintJobs.WORDERKey = #WORDERKey
END
Thanks,
Stacy
One way would be to look at TOP and ORDER BY, i.e.
SELECT TOP 1
PrintJobs.WORDERKey,
PrintJobs.JobNumber,
WORDER.U_DateRequired AS DateRequired,
ProductMaster.PartFileItemID,
WORDER.ManufacturingDepartment AS MfgDept,
PrintJobs.Copies AS LabelCopies,
PrintJobs.ExpiryDate AS JobExpiryDate,
PrintJobs.Batch,
PrintJobs.JulianDate AS JobJulianDate,
ProductMaster.Description,
ProductMaster.PackFormat,
ProductMaster.IngDec,
ProductMaster.BarCodeNumber,
ProductMaster.CustomerProductCode,
ProductMaster.CriticalInstruction,
ProductMaster.StorageInstruction,
ProductMaster.MixedCaseTitle,
ProductMaster.MixedCode1,
ProductMaster.MixedCode2,
ProductMaster.MixedCode3,
ProductMaster.MixedCode4,
ProductMaster.MixedDescription1,
ProductMaster.MixedDescription2,
ProductMaster.MixedDescription3,
ProductMaster.MixedDescription4,
ProductMaster.MixedIngDec1,
ProductMaster.MixedIngDec2,
ProductMaster.MixedIngDec3,
ProductMaster.MixedIngDec4,
ProductMaster.CookingInstruction,
ProductMaster.LogoFilename,
ProductMaster.ProductExpiryRule,
ExpiryRulesMaster.GS1_AppID,
ProductMaster.LabelTemplateID,
CASE WHEN ProductMaster.PartFileItemID IS NULL THEN 'N' ELSE 'Y' END AS LabelDefExists,
LabelTemplateMaster.FileName,
CASE WHEN [DateFormat] = 'Default' THEN ExpiryRulesMaster.DateFormatString ELSE [DateFormat] END AS DateFormatString,
ExpiryRulesMaster.DateRounding,
ExpiryRulesMaster.ExcludeXmasNewYear,
PART.ExternalShelfLifeTotalDays,
CustomOptions.Tagline,
CustomOptions.ShortName AS CustShortName,
ExpiryRulesMaster.LabelText AS ExpiryRuleLabelText,
ProductMaster.inner_hDescription,
ProductMaster.inner_vDescription,
ProductMaster.inner_CustCode,
ProductMaster.inner_Storage,
ProductMaster.inner_WarningMsg,
ProductMaster.inner_Dateformat,
ProductMaster.inner_SpecialCode,
ProductMaster.LabelType,
ProductMaster.inner_MicroSuiteCode,
ProductMaster.inner_PackWeight,
ProductMaster.inner_JDateFormat,
ProductMaster.CustomOptionID,
ProductMaster.inner_PrintLogo,
PART.NominalWeight,
ProductMaster.IngDec_html,
ProductMaster.IngDec_Active,
PrintJobs.PrintJobsID,
MaxJobs.MaxJob,
PrintJobs.DateEntered
FROM ProductMaster RIGHT OUTER JOIN
(
SELECT Partfileitemid,
--JobNumber,
MAX(dateentered) MaxJob
FROM PrintJobs
GROUP BY PartFileItemID
)
MaxJobs ON ProductMaster.PartFileItemID = MaxJobs.PartFileItemID RIGHT OUTER JOIN
PrintJobs ON PrintJobs.PartFileItemID = MaxJobs.PartFileItemID RIGHT OUTER JOIN
LabelTemplateMaster ON ProductMaster.LabelTemplateID = LabelTemplateMaster.LabelTemplateID LEFT OUTER JOIN
CustomOptions ON ProductMaster.CustomOptionID = CustomOptions.CustomOptionID LEFT OUTER JOIN
ExpiryRulesMaster ON ProductMaster.ProductExpiryRule = ExpiryRulesMaster.ExpiryRule LEFT OUTER JOIN
[F8Extract].[dbo].[WORDER] ON PrintJobs.WORDERKey = WORDER.WORDERKey LEFT OUTER JOIN
[F8Extract].[dbo].[PART] ON ProductMaster.PartFileItemID = Part.PartFileItemID
WHERE PrintJobs.WORDERKey = #WORDERKey
ORDER BY PrintJobs.Number DESC
Note change the PrintJobs.Number to whatever field specifies the time order.

Join with Zend_Db, without having the columns of the joined tables

I use Zend_Db_Select to perform a query with a Join. I end up with the following SQL query :
SELECT `Utilisateur`.*, `Ressource`.*, `Acl_Cache`.*, `Role`.*, `UtilisateurRole`.* FROM `Utilisateur`
INNER JOIN `Ressource` ON Ressource.idJointure = Utilisateur.id
INNER JOIN `Acl_Cache` ON Acl_Cache.idRessource = Ressource.id
INNER JOIN `Role` ON Role.id = Acl_Cache.idRole
INNER JOIN `UtilisateurRole` ON UtilisateurRole.idRole = Role.id
WHERE (Ressource.tableJointure = 'Utilisateur') AND (UtilisateurRole.idUtilisateur = '2')
Why is Zend_Db adding this part is the SELECT clause :
, `Ressource`.*, `Acl_Cache`.*, `Role`.*, `UtilisateurRole`.*
I never asked this, and I don't want that. How to prevent this behavior ?
$db->select()
->from(array('alias1'=>'table_i_want_all_cols_on'))
->joinLeft(array('alias2'=>'table_i_want_no_cols_on'),
'alias1.id = alias2.id',
array()
)
->joinLeft(array('alias3'=>'table_i_want_some_cols_on'),
'alias3.id = alias1.id',
array('col1', 'col2')
);