Select statement where joins causing records to be excluded - sql

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'

Related

Comparing values in two rows and getting ORA-00918: column ambiguously defined

I am trying to compare values from one column in two different rows using CASE statement. Inner SELECT statements are identical and working OK giving me fields that I need. Then I inner joined them on one of the key fields (KYCID). That's where I get "column ambiguously defined" error. I tried to remove duplicate rows by using DISTINCT - still the same error.
SELECT DISTINCT e.KYCID,
CASE WHEN e.HRAC_FLAG <> f.HRAC_FLAG THEN 'FALSE' ELSE 'TRUE' END AS FLAG_COMPARISON
FROM
(SELECT gt.task_id, gt.work_item_status, gt.work_item_type, gt.component_id, xref.HRAC_FLAG,
xref.case_nbr, xref.task_id, d.kycid, d.core_component_state
FROM kyc_gbl_main.global_task gt
inner join KYC_RGN_NAM_MAIN.CASE_HRAC_XREF xref on gt.component_id = xref.component_id
inner join kyc_rgn_nam_main.account a on xref.accountid = a.accountid
inner join kyc_rgn_nam_main.country_appx_account_xref b on a.accountid = b.accountid
inner join kyc_rgn_nam_main.country_appx c on c.cntry_appx_id = b.cntry_appx_id and
c.country_appx_state = b.country_appx_state
inner join kyc_rgn_nam_main.kyc_main d on d.kycid = c.kycid
where gt.work_item_type = 'HRAC_OVERLAY'
and gt.work_item_status = 'Completed') e
INNER JOIN
(select gt.task_id, gt.work_item_status, gt.work_item_type, gt.component_id, xref.HRAC_FLAG,
xref.case_nbr, xref.task_id, d.kycid, d.core_component_state
from kyc_gbl_main.global_task gt
inner join KYC_RGN_NAM_MAIN.CASE_HRAC_XREF xref on gt.component_id = xref.component_id
inner join kyc_rgn_nam_main.account a on xref.accountid = a.accountid
inner join kyc_rgn_nam_main.country_appx_account_xref b on a.accountid = b.accountid
inner join kyc_rgn_nam_main.country_appx c on c.cntry_appx_id = b.cntry_appx_id and
c.country_appx_state = b.country_appx_state
inner join kyc_rgn_nam_main.kyc_main d on d.kycid = c.kycid
where gt.work_item_type = 'HRAC_OVERLAY'
and gt.work_item_status = 'Completed') f
ON e.KYCID = f.KYCID
WHERE e.core_component_state ='ACTIVE'
AND f.core_component_state = 'IN_PROGRESS';
As determined with process of elimination, you reference the same named column in a SELECT query. To avoid this name collision, consider aliasing those particular columns.
Additionally, to avoid repetition, consider using a CTE via WITH and avoid using table aliases like (a, b, c) or (t1, t2, t3). Finally, move WHERE conditions to ON to filter before combining all data sources.
WITH sub AS (
SELECT gt.task_id AS gt_task_id -- RENAMED TO AVOID COLLISION
, gt.work_item_status
, gt.work_item_type
, gt.component_id
, xref.HRAC_FLAG
, xref.case_nbr
, xref.task_id AS x_ref_task_id -- RENAMED TO AVOID COLLISION
, k.kycid
, k.core_component_state
FROM kyc_gbl_main.global_task gt
INNER JOIN KYC_RGN_NAM_MAIN.CASE_HRAC_XREF xref
ON gt.component_id = xref.component_id
AND gt.work_item_type = 'HRAC_OVERLAY' -- MOVED FROM WHERE
AND gt.work_item_status = 'Completed' -- MOVED FROM WHERE
INNER JOIN kyc_rgn_nam_main.account acc
ON xref.accountid = acc.accountid
INNER JOIN kyc_rgn_nam_main.country_appx_account_xref cax
ON acc.accountid = cax.accountid
INNER JOIN kyc_rgn_nam_main.country_appx ca
ON ca.cntry_appx_id = cax.cntry_appx_id
AND ca.country_appx_state = cax.country_appx_state
INNER JOIN kyc_rgn_nam_main.kyc_main k
ON k.kycid = ca.kycid
)
SELECT DISTINCT
e.KYCID
, CASE
WHEN e.HRAC_FLAG <> f.HRAC_FLAG
THEN 'FALSE'
ELSE 'TRUE'
END AS FLAG_COMPARISON
FROM sub e
INNER JOIN sub f
ON e.KYCID = f.KYCID
AND e.core_component_state = 'ACTIVE' -- MOVED FROM WHERE
AND f.core_component_state = 'IN_PROGRESS' -- MOVED FROM WHERE

SQL Query with counts only returning equivalent counts

I have a query that consists of 1 table and 2 sub queries. The table being a listing of all customers, 1 sub query is a listing all of the quotes given over a period of time for customers and the other sub query is a listing of all of the orders booked for a customer over the same period of time. What I am trying to do is return a result set that is a customer, the number of quotes given, and the number of orders booked over a given period of time. However what I am returning is only a listening of customers over the period of time that have an equivalent quote and order count. I feel like I am missing something obvious within the context of the query but I am unable to figure it out. Any help would be appreciated. Thank you.
Result Set should look like this
Customer-------Quotes-------Orders Placed
aaa----------------4----------------4
bbb----------------9----------------18
ccc----------------18----------------9
select
[Customer2].[Name] as [Customer2_Name],
(count( Quotes.UD03_Key3 )) as [Calculated_CustomerQuotes],
(count( Customer_Bookings.OrderHed_OrderNum )) as [Calculated_CustomerBookings]
from Erp.Customer as Customer2
left join (select
[UD03].[Key3] as [UD03_Key3],
[UD03].[Key4] as [UD03_Key4],
[UD03].[Key1] as [UD03_Key1],
[UD03].[Date02] as [UD03_Date02]
from Ice.UD03 as UD03
inner join Ice.UD02 as UD02 on
UD03.Company = UD02.Company
And
CAST(CAST(UD03.Number09 AS INT) AS VARCHAR(30)) = UD02.Key1
left outer join Erp.Customer as Customer on
UD03.Company = Customer.Company
And
UD03.Key1 = Customer.Name
left outer join Erp.SalesTer as SalesTer on
Customer.Company = SalesTer.Company
And
Customer.TerritoryID = SalesTer.TerritoryID
left outer join Erp.CustGrup as CustGrup on
Customer.Company = CustGrup.Company
And
Customer.GroupCode = CustGrup.GroupCode
where (UD03.Key3 <> '0')) as Quotes on
Customer2.Name = Quotes.UD03_Key1
left join (select
[Customer1].[Name] as [Customer1_Name],
[OrderHed].[OrderNum] as [OrderHed_OrderNum],
[OrderDtl].[OrderLine] as [OrderDtl_OrderLine],
[OrderHed].[OrderDate] as [OrderHed_OrderDate]
from Erp.OrderHed as OrderHed
inner join Erp.Customer as Customer1 on
OrderHed.Company = Customer1.Company
And
OrderHed.BTCustNum = Customer1.CustNum
inner join Erp.OrderDtl as OrderDtl on
OrderHed.Company = OrderDtl.Company
And
OrderHed.OrderNum = OrderDtl.OrderNum) as Customer_Bookings on
Customer2.Name = Customer_Bookings.Customer1_Name
where Quotes.UD03_Date02 >= '5/15/2018' and Quotes.UD03_Date02 <= '5/15/2018' and Customer_Bookings.OrderHed_OrderDate >='5/15/2018' and Customer_Bookings.OrderHed_OrderDate <= '5/15/2018'
group by [Customer2].[Name]
You have several problems going on here. The first problem is your code is so poorly formatted it is user hostile to look at. Then you have left joins being logically treated an inner joins because of the where clause. You also have date literal strings in language specific format. This should always be the ANSI format YYYYMMDD. But in your case your two predicates are contradicting each other. You have where UD03_Date02 is simultaneously greater than and less than the same date. Thankfully you have =. But if your column is a datetime you have prevented any rows from being returned again (the first being your where clause). You have this same incorrect date logic and join in the second subquery as well.
Here is what your query might look like with some formatting so you can see what is going on. Please note I fixed the logical join issue. You still have the date problems because I don't know what you are trying to accomplish there.
select
[Customer2].[Name] as [Customer2_Name],
count(Quotes.UD03_Key3) as [Calculated_CustomerQuotes],
count(Customer_Bookings.OrderHed_OrderNum) as [Calculated_CustomerBookings]
from Erp.Customer as Customer2
left join
(
select
[UD03].[Key3] as [UD03_Key3],
[UD03].[Key4] as [UD03_Key4],
[UD03].[Key1] as [UD03_Key1],
[UD03].[Date02] as [UD03_Date02]
from Ice.UD03 as UD03
inner join Ice.UD02 as UD02 on UD03.Company = UD02.Company
And CAST(CAST(UD03.Number09 AS INT) AS VARCHAR(30)) = UD02.Key1
left outer join Erp.Customer as Customer on UD03.Company = Customer.Company
And UD03.Key1 = Customer.Name
left outer join Erp.SalesTer as SalesTer on Customer.Company = SalesTer.Company
And Customer.TerritoryID = SalesTer.TerritoryID
left outer join Erp.CustGrup as CustGrup on Customer.Company = CustGrup.Company
And Customer.GroupCode = CustGrup.GroupCode
where UD03.Key3 <> '0'
) as Quotes on Customer2.Name = Quotes.UD03_Key1
and Quotes.UD03_Date02 >= '20180515'
and Quotes.UD03_Date02 <= '20180515'
left join
(
select
[Customer1].[Name] as [Customer1_Name],
[OrderHed].[OrderNum] as [OrderHed_OrderNum],
[OrderDtl].[OrderLine] as [OrderDtl_OrderLine],
[OrderHed].[OrderDate] as [OrderHed_OrderDate]
from Erp.OrderHed as OrderHed
inner join Erp.Customer as Customer1 on OrderHed.Company = Customer1.Company
And OrderHed.BTCustNum = Customer1.CustNum
inner join Erp.OrderDtl as OrderDtl on OrderHed.Company = OrderDtl.Company
And OrderHed.OrderNum = OrderDtl.OrderNum
) as Customer_Bookings on Customer2.Name = Customer_Bookings.Customer1_Name
and Customer_Bookings.OrderHed_OrderDate >= '20180515'
and Customer_Bookings.OrderHed_OrderDate <= '20180515'
group by [Customer2].[Name]
COUNT() will just give you the number of records. You'd expect this two result columns to be equal. Try structuring it like this:
SUM(CASE WHEN Quote.UD03_Key1 IS NOT NULL THEN 1 ELSE 0 END) AS QuoteCount,
SUM(CASE WHEN Customer_Bookings.Customer1_Name IS NOT NULL THEN 1 ELSE 0 END) AS custBookingCount

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

Avoiding NULL records on this LEFT JOIN

The query below works - EXCEPT - it is returning NULL values for vehicle_id. I do not want any records that have NULL for vehicle_id.
Since vehicle_id is tied to fund_series, this is complicated to me.
When I had the vehicle_id conditions underneath the WHERE, the query was not working. Any SQL geniuses that can help?
I put the MIN() aggregate functions in there just so I could get the GROUP BY to work.
SELECT DISTINCT
MIN(ml.pretty_file_name),
ml.filename,
MIN(ml.issued_date),
MIN(mr.rule_name),
MIN(mlob.line_of_business_name),
MIN(mt.media_type_name),
MAX(v.vehicle_name)
FROM Media_Live ml
JOIN Media_Type mt
ON mt.media_type_id = ml.media_type_id
JOIN Media_Rule mr
ON mr.rule_id = ml.rule_id
JOIN Media_Line_Of_Business mlob
ON mlob.line_of_business_id = ml.line_of_business_id
LEFT JOIN Fund_Class_Media fcm
ON fcm.media_id=ml.media_id
LEFT JOIN Fund_Class_Live fc
ON fc.fund_class_id = fcm.fund_class_id
LEFT JOIN Fund_Series fs
ON fs.fund_series_id = fc.fund_series_id
LEFT JOIN Vehicle AS v
ON v.vehicle_id=fs.vehicle_id AND /*THIS IS WHERE IM GETTING NULLS*/
(
v.vehicle_id = 1
OR v.vehicle_id = 2
OR v.vehicle_id = 5
)
LEFT JOIN Media_Media_Tag AS mmt ON mmt.media_id=ml.media_id
LEFT JOIN Media_Tag AS mtag ON mtag.tag_id=mmt.tag_id
WHERE
(/*people can search with terms for fc*/
--fc.fund_class_id LIKE '%'+replace(?,' ','%')+'%'
)
(
mt.media_type_id = 33
OR mt.media_type_id = 1
OR mt.media_type_id = 12
)
AND
(
mr.rule_id = 3
OR mr.rule_id = 9
)
AND
(
mtag.tag_name != 'exclude_web_lit_center'
)
GROUP BY ml.filename
This is what a left join does, allow nulls. Just take out the left join part making it an inner join.
JOIN Vehicle AS v ON v.vehicle_id=fs.vehicle_id AND v.vehicle_id IN (1,2,5)
You cold also do this, but I don't see why you would:
LEFT JOIN Vehicle AS v ON v.vehicle_id=fs.vehicle_id AND ISNULL(v.vehicle_id,0) IN (1,2,5)
In the WHERE clause, add:
AND v.Vehicl_Id IS NOT NULL
That should do it.

SQL Outer Join on a bunch of Inner Joined results

I received some great help on joining a table to itself and am trying to take it to the next level. The SQL below is from the help but with my addition of the select line beginning with COUNT, the inner join to the Recipient table, and the Group By.
SELECT
Event.EventID AS EventID,
Event.EventDate AS EventDateUTC,
Participant2.ParticipantID AS AwayID,
Participant1.ParticipantID AS HostID,
COUNT(Recipient.ChallengeID) AS AllChallenges
FROM Event
INNER JOIN Matchup Matchup1
ON (Event.EventID = Matchup1.EventID)
INNER JOIN Matchup Matchup2
ON (Event.EventID = Matchup2.EventID)
INNER JOIN Participant Participant1
ON (Matchup1.Host = 1
AND Matchup1.ParticipantID = Participant1.ParticipantID)
INNER JOIN Participant Participant2
ON (Matchup2.Host != 1
AND Matchup2.ParticipantID = Participant2.ParticipantID)
INNER JOIN Recipient
ON (Event.EventID = Recipient.EventID)
WHERE Event.CategoryID = 1
AND Event.Resolved = 0
AND Event.Type = 1
GROUP BY Recipient.ChallengeID
ORDER BY EventDateUTC ASC
My goal is to get a count of how many rows in the Recipient table match the EventID in Event. This code works fine except that I also want to get results where there are 0 matching rows in Recipient. I want 15 rows (= the number of events) but I get 2 rows, one with a count of 1 and one with a count of 2 (which is appropriate for an inner join as there are 3 rows in the sample Recipient table, one for one EventID and two for another EventID).
I thought that either a LEFT join or an OUTER join was what I was looking for, but I know that I'm not quite getting how the tables are actually joined. A LEFT join there gives me one more row with 0, which happens to be EventID 1 (first thing in the table), but that's all. Errors advise me that I can't just change that INNER join to an OUTER. I tried some parenthesizing and some subselects and such but can't seem to make it work.
Use:
SELECT e.eventid,
e.eventdate AS EventDateUTC,
p2.participantid AS AwayID,
p1.participantid AS HostID,
COUNT(r.challengeid) AS AllChallenges
FROM EVENT e
JOIN Matchup m1 ON m1.eventid = e.eventid
AND m1.host = 1
JOIN Matchup m2 ON m2.eventid = e.eventid
AND m2.host != 1
JOIN Participant p1 ON p1.participantid = m1.participantid
JOIN Participant p2 ON p2.participantid = m2.participantid
LEFT JOIN RECIPIENT r ON r.eventid = e.eventid
WHERE e.categoryid = 1
AND e.resolved = 0
AND e.type = 1
GROUP BY e.eventid, e.eventdate, p2.participantid, p1.participantid
ORDER BY e.eventdate