SQL Query to apply join on basis of case Condition - sql

I have a requirement where I need to fetch the Dimension Key of Region table on basis of the following preference.
Fetch dimension key on basis of Zipcode of Physical address(PA)
If the first condition is not satisfied that fetch dimension key on basis of the Zip Code of the Mailing address
If the second condition is also not satisfied than fetch the dimension key on basis of the Parish Code of Physical address
Else fetch dimension key on basis of parish Code of Mailing address.
I am trying to use the below query but is giving multiple records since all left joins are getting evaluated. I want that it should not go on the second condition if the first condition is satisfied.
select REGION_DIM_SK, CASE_NUM
from (
select distinct COALESCE(RDIM.REGION_DIM_SK, RDIM1.REGION_DIM_SK, RDIM2.REGION_DIM_SK, RDIM3.REGION_DIM_SK) AS REGION_DIM_SK
, DC.CASE_NUM, ADDR_TYPE_CD
FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS dc
left join rpt_dm_ee_prsnt.REGION_DIM RDIM on dc.ZIP_CODE = RDIM.ZIP_CODE and RDIM.REGION_EFF_END_DT IS NULL and dc.addr_type_cd='PA' AND dc.EFF_END_DT IS NULL
left join rpt_dm_ee_prsnt.REGION_DIM RDIM1 ON dc.ZIP_CODE = RDIM1.ZIP_CODE AND RDIM1.REGION_EFF_END_DT IS NULL AND dc.addr_type_cd='MA' AND DC.EFF_END_DT IS NULL
left join (
select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
from rpt_dm_ee_prsnt.REGION_DIM
where REGION_EFF_END_DT is null
group by PARISH_CD
) RDIM2 ON dc.addr_type_cd='PA' and dc.PARISH_CD = RDIM2.PARISH_CD AND DC.EFF_END_DT IS NULL
left join (
select PARISH_CD, min(REGION_DIM_SK) as REGION_DIM_SK
from rpt_dm_ee_prsnt.REGION_DIM
where REGION_EFF_END_DT is null
group by PARISH_CD
) RDIM3 ON dc.addr_type_cd='MA' and dc.PARISH_CD = RDIM3.PARISH_CD AND DC.EFF_END_DT IS NULL
) A
where REGION_DIM_SK is not null
) RD on RD.case_num = rpt_dm_ee_intg.CASE_PERSON_ELIGIBILITY.CASE_NUM

Use multiple left joins. Your query is rather hard to follow -- it has other tables and references not described in the problem.
But the idea is:
select t.*,
coalesce(rpa.dim_key, rm.dim_key, rpap.dim_key, rmp.dim_key) as dim_key
from t left join
dim_region rpa
on t.physical_address_zipcode = rpa.zipcode left join
dim_region rm
on t.mailing_address_zipcode = rm.zipcode and
rpa.zipcode is null left join
dim_region rpap
on t.physical_addresss_parishcode = rpap.parishcode and
rm.zipcode is null left join
dim_region rmp
on t.physical_addresss_parishcode = rmp.parishcode and
rpap.zipcode is null

The trick is to put the conditions in CASE WHEN:
SELECT *
FROM table1 a
JOIN table2 b
ON CASE
WHEN a.code is not null and a.code = b.code THEN 1
WHEN a.type = b.type THEN 1
ELSE 0
END = 1
For your example you can reduce the code to just two joins, it can't be done in one as you are joining two different tables.
SELECT CASE WHEN RDIM.addres IS NULL THEN RDIM2.addres ELSE RDIM.addres
FROM rpt_dm_ee_intg.CASE_PERSON_ADDRESS dc
LEFT JOIN rpt_dm_ee_prsnt.REGION_DIM RDIM ON CASE
WHEN (dc.ZIP_CODE = RDIM.ZIP_CODE
AND RDIM.REGION_EFF_END_DT IS NULL
AND dc.addr_type_cd='PA'
AND dc.EFF_END_DT IS NULL) THEN 1
WHEN (dc.ZIP_CODE = RDIM1.ZIP_CODE
AND RDIM1.REGION_EFF_END_DT IS NULL
AND dc.addr_type_cd='MA'
AND DC.EFF_END_DT IS NULL) THEN 1
ELSE 0
END = 1
LEFT JOIN
(SELECT PARISH_CD,
min(REGION_DIM_SK) AS REGION_DIM_SK
FROM rpt_dm_ee_prsnt.REGION_DIM
WHERE REGION_EFF_END_DT IS NULL
GROUP BY PARISH_CD) RDIM2 ON CASE
WHEN (dc.addr_type_cd='PA'
AND dc.PARISH_CD = RDIM2.PARISH_CD
AND DC.EFF_END_DT IS NULL
AND RDIM.ZIP_CODE IS NULL) THEN 1
WHEN (dc.addr_type_cd='MA'
AND dc.PARISH_CD = RDIM3.PARISH_CD
AND DC.EFF_END_DT IS NULL
AND RDIM.ZIP_CODE IS NULL) THEN 1
ELSE 0
END = 1
edit
If you don't want to have nulls from RDIM2 table if RDIM1 zip code is present the logic could be easily extended to support that. You just need to add AND RDIM.ZIP_CODE IS NULL to CASE WHEN conditions.

Related

T-SQL Full Outer Join (sample provided)

I have some issues getting a full outer join to work in T-SQL. The left outer join part seems to be working okay, but the right outer join doesn't work as expected. Here's some sample data to test this on:
I have a table A with the following columns and data. The row marked with red is the row that cannot be found in table B.
And a second table B with the following columns and data. The rows marked with yellow are the rows that cannot be found in table A.
I am trying to join the tables using the following sql code:
select tableA.klientnr, tableA.uttakstype, tableA.uttaksnr, tableA.vareanr TableAItem,tableB.vareanr tableBitem, tableA.kvantum tableAquantity, tableB.totkvant tableBquantity
from tableA as tableA
full outer join tableB as tableB on tableA.klientnr=tableB.klientnr and tableA.uttakstype=tableB.uttakstype and tableA.uttaksnr=tableB.uttaksnr and tableA.vareanr=tableB.vareanr and tableB.IsDeleted=0
where tableA.UttaksNr=639779 and tableA.IsDeleted=0
The result of the sql is the following image. The row marked in red is the extra row from tableA that does show up, but I can't get the rows from table B to show up
Expected to have 2 extra rows
550 SA 639779 NULL 100059 NULL 0
550 SA 639779 NULL 103040 NULL 14
Later edit:
Would this be correct way to handle the full outer join where there's the header/line type of structure? Or can the query be optimized?
SELECT ISNULL(q1.accountid, q2.accountid) AccountId
,ISNULL(q1.klientnr, q2.klientnr) KlientNr
,ISNULL(q1.tilgangstype, q2.tilgangstype) 'Reception Type'
,ISNULL(q1.tilgangsnr, q2.tilgangsnr) 'Reception No'
,ISNULL(q1.dato, q2.dato) dato
,ISNULL(q1.LevNr, q2.LevNr) LevNr
,ISNULL(q1.Pakkemerke, q2.Pakkemerke) Pakkemerke
,ISNULL(q1.VareANr, q2.VareANr) VareANr
,ISNULL(q1.Ankomstdato,q2.Ankomstdato) 'Arrival Date'
,q1.Antall1
,q1.totkvant1
,q1.Antall2
,q1.totkvant2
,q2.Antall
,q2.totkvant
,q2.AntallTilFrys
,q2.TotKvantTilFrys
,ISNULL(q1.EksternKommentar1,q2.EksternKommentar1) EksternKommentar1
,q2.[Last Upsert]
FROM (
SELECT w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w789.VareANr
,sum(IIF(w789.prognosetype = 1, w789.Antall, NULL)) AS Antall1
,sum(IIF(w789.prognosetype = 1, w789.totkvant, NULL)) AS totkvant1
,sum(IIF(w789.prognosetype = 2, w789.Antall, NULL)) AS Antall2
,sum(IIF(w789.prognosetype = 2, w789.totkvant, NULL)) AS totkvant2
,w700.EksternKommentar1
FROM trading.W789Prognosekjopstat AS w789
INNER JOIN trading.W700Tilgangshode AS w700 ON w700.AccountId = w789.AccountId
AND w700.KlientNr = w789.Klientnr
AND w700.Tilgangsnr = w789.Tilgangsnr
AND w700.Tilgangstype = w789.Tilgangstype
AND w700.IsDeleted = 0
WHERE w789.IsDeleted = 0
GROUP BY w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w789.VareANr
,w700.EksternKommentar1
) q1
FULL OUTER JOIN (
SELECT w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w702.VareANr
,w702.Antall
,w702.TotKvant
,w702.ValPris
,w702.AntallTilFrys
,w702.TotKvantTilFrys
,w700.EksternKommentar1
,(SELECT MAX(LastUpdateDate) FROM (VALUES (w702.createdAt),(w702.updatedAt)) AS UpdateDate(LastUpdateDate)) AS 'Last Upsert'
FROM trading.w702PrognoseKjop w702
INNER JOIN trading.W700Tilgangshode AS w700 ON w700.AccountId = w702.AccountId
AND w700.KlientNr = w702.Klientnr
AND w700.Tilgangsnr = w702.Tilgangsnr
AND w700.Tilgangstype = w702.Tilgangstype
AND w700.IsDeleted = 0
WHERE w702.IsDeleted = 0
) q2 ON q1.accountid = q2.accountid
AND q1.klientnr = q2.klientnr
AND q1.tilgangstype = q2.tilgangstype
AND q1.tilgangsnr = q2.tilgangsnr
AND q1.vareanr = q2.vareanr
WHERE totkvant1 IS NOT NULL
OR totkvant2 IS NOT NULL
OR totkvant IS NOT NULL
Filtering with full join is really tricky. Your where criteria are actually turning the full join into a left join.
You can do what you want by filtering before the join:
select a.klientnr, a.uttakstype, a.uttaksnr, a.vareanr a.tableAitem,
b.vareanr b.tableBitem, a.kvantum a.tableAquantity, b.totkvant b.tableBquantity
from (select a.*
from tableA a
where a.UttaksNr = 639779 and a.IsDeleted = 0
) a full join
(select b.*
from tableB b
where b.IsDeleted = 0
) b
on a.klientnr = b.klientnr and
a.uttakstype= b.uttakstype and
a.uttaksnr = b.uttaksnr and
a.vareanr = b.vareanr;

How to pass default value to selected column name if null found with inner join with SQL

I have a SQL query that shows details of jobs. here I have check if null value found with inner join then pass with precondition.
Here is my SQL query :
SELECT
Jobs.EmailsSent,
Jobs.SubscriberCount,
Jobs.CompletedOn,
Jobs.PreparedEmailID,
Jobs.JobID,
Jobs.CreatedOn,
tbl_Categories.CategoryName,
tbl_Email_master.Title,
tbl_From_master.Name As FromUsername,
tbl_User_master.Name AS CreatedBy
FROM
Jobs
INNER JOIN
tbl_Email_master ON Jobs.PreparedEmailID = tbl_Email_master.Id
INNER JOIN
tbl_From_master ON Jobs.FromuserID = tbl_From_master.Id
AND tbl_Email_master.FromUser = tbl_From_master.Id
INNER JOIN
tbl_Categories ON tbl_Categories.Id = Jobs.CategoryID
OR (tbl_Categories.Id IS NOT NULL
AND Jobs.CategoryID IS NULL)
-- here pass default value like ALL if Jobs.CategoryID found NULL
INNER JOIN
tbl_User_master ON Jobs.UserID = tbl_User_master.Id
AND tbl_Email_master.user_id = tbl_User_master.Id
AND tbl_From_master.user_id = tbl_User_master.Id
AND tbl_Categories.user_id = tbl_User_master.Id
WHERE
Jobs.JobID = '7'
Can we do with this?
--------------------------------updated--------------------------------
with this ans :
INNER JOIN tbl_Categories ON tbl_Categories.Id = coalesce(Jobs.CategoryID,tbl_Categories.Id) OR (tbl_Categories.Id IS NOT NULL AND coalesce(Jobs.CategoryID,tbl_Categories.Id)=tbl_Categories.Id)
i have retrieving row like :
now I just only want raws/raw with default category value ALL.
--------------------------------as text----------------------------------
CATEGORY NAME
0 44 NULL Friends
0 44 NULL Family Relatives
0 44 NULL Business Clients
0 44 NULL Corporate Profiles
0 44 NULL test
0 44 NULL Infisms Clients
0 44 NULL Infisms Clients
here i just want to return row/rows with Category Name as ALL.
Just use coalesce() function
...tbl_Categories.Id = coalesce(Jobs.CategoryID,tbl_Categories.Id) OR
(tbl_Categories.Id IS NOT NULL
AND coalesce(Jobs.CategoryID,tbl_Categories.Id)=tbl_Categories.Id)
assuming tbl_Categories.Id is a non-null column
You could try this:
INNER JOIN
tbl_Categories ON tbl_Categories.Id = isnull(Jobs.CategoryID, tbl_Categories.Id)

Looking for a way to not show duped rows using a SQL query

SELECT
AEC.gwd_people.id_people,
AEC.gwd_people.uid_people,
AEC.gwd_people.cod_people,
AEC.gwd_people.name_people,
AEC.gwd_people.surname_people,
AEC.gwd_people.email,
AEC.gwd_people.people_status,
AEC.gwd_people.people_type,
AEC.gwd_people.facility_reference,
AEC.gwd_people.sc_id_sap,
AEC.gwd_people.c_id_sap,
AEC.gwd_people.descr_people,
AEC.gwd_people.cod_sector,
AEC.gwd_people.descr_sector,
AEC.gwd_people.cod_org_sector,
AEC.gwd_people.descr_org_sector,
AEC.gwd_people.cod_company,
AEC.gwd_people.descr_company,
AEC.gwd_people.cod_company_sap,
AEC.gwd_people.cod_department,
AEC.gwd_department.descr_department,
AEC.gwd_people.cod_subdepartment,
AEC.gwd_people.descr_subdepartment,
AEC.gwd_people.cod_cdc,
AEC.gwd_cost_center.descr_cdc,
AEC.gwd_people.cod_category_job,
AEC.gwd_people.descr_category_job,
AEC.gwd_people.cod_people_job,
AEC.gwd_people.descr_people_job,
AEC.gwd_people.cod_position,
AEC.gwd_people.descr_position,
AEC.gwd_people.uohr,
AEC.gwd_people.qual_contract,
AEC.gwd_people.level_position,
AEC.gwd_people.cod_manager,
AEC.gwd_people.cod_validator,
AEC.gwd_people.cod_country,
AEC.gwd_people.descr_country,
AEC.gwd_people.cod_region_area,
AEC.gwd_people.descr_region_area,
AEC.gwd_people.descr_city,
AEC.gwd_people.descr_site,
AEC.gwd_people.address_1,
AEC.gwd_people.address_2,
AEC.gwd_people.descr_building,
AEC.gwd_people.descr_room,
AEC.gwd_people.validity_date,
AEC.aec_workstation.cod_workstation,
AEC.aec_workstation.geometry,
AEC.aec_workstation.drawing,
AEC.gwd_people.tax_code,
AEC.gwd_people.phone_1,
AEC.gwd_people.phone_2,
AEC.gwd_people.phone_3,
AEC.gwd_people.phone_4,
AEC.gwd_people.ext_email_1,
AEC.gwd_people.flagvip,
AEC.gwd_people.hiring_date,
AEC.gwd_people.cease_date,
AEC.gwd_people.cid_resp_liv_1,
AEC.gwd_people.cid_resp_liv_2,
AEC.gwd_people.id_resp,
AEC.gwd_people.descr_resp,
AEC.gwd_people.id_ref,
AEC.gwd_people.descr_ref,
AEC.gwd_people.descr_ext_people,
AEC.gwd_people.ext_email_2,
AEC.gwd_people.descr_sede,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NULL
THEN AEC.gwd_people.idplan
ELSE NULL
END) AS idplan,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NOT NULL
THEN SUBSTRING(AEC.aec_workstation.cod_workstation, 5, 7)
ELSE NULL
END) AS idplan_wrkst,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NULL
THEN AEC.view_iam_r_unitp_building.IDEDIFICIO
ELSE NULL
END) AS cod_building,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NOT NULL
THEN SUBSTRING(AEC.aec_workstation.cod_workstation, 5, 3)
ELSE NULL
END) AS cod_building_wrkst,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NOT NULL
THEN AEC.aec_workstation.id_room
ELSE NULL
END) AS id_room_wrkst,
(CASE WHEN AEC.aec_r_workstation_people.cod_people IS NOT NULL
THEN AEC.aec_workstation.id_room
ELSE NULL
END) AS id_room_wrkst2
FROM AEC.gwd_people
LEFT OUTER JOIN AEC.view_iam_r_unitp_building ON
AEC.view_iam_r_unitp_building.IDUNITPROD = AEC.gwd_people.cod_sector
LEFT OUTER JOIN AEC.aec_r_workstation_people ON AEC.gwd_people.cod_people =
AEC.aec_r_workstation_people.cod_people
LEFT OUTER JOIN AEC.aec_workstation ON AEC.aec_workstation.cod_workstation
= AEC.aec_r_workstation_people.cod_workstation
LEFT OUTER JOIN AEC.gwd_department ON AEC.gwd_department.cod_department =
AEC.gwd_people.cod_department
LEFT OUTER JOIN AEC.gwd_cost_center ON AEC.gwd_cost_center.cod_cost_center
= AEC.gwd_people.cod_cdc
This is my query and I'm using SQL Server 13, it returns 6752 rows, 44 of them are duped. I've tried everything I know to avoid showing those duped entries but I'm out of ideas, so I'm looking for some helpful tips :-) One of the biggest problem is taht all fields are necessary, so I can't get rid of "AEC.aec_workstation.geometry" that causes problems with SELECT DISTINCT.
Find a PK value from your first table that's returning a duplicate row and start with the following query:
SELECT
COUNT(1)
FROM
AEC.gwd_people
WHERE
AEC.gwd_people.PrimaryKeyColumn = 'SomeValue'
Now start adding joins one by one, checking the result of the COUNT(1) each time:
SELECT
COUNT(1)
FROM
AEC.gwd_people
LEFT OUTER JOIN AEC.view_iam_r_unitp_building ON AEC.view_iam_r_unitp_building.IDUNITPROD = AEC.gwd_people.cod_sector
WHERE
AEC.gwd_people.PrimaryKeyColumn = 'SomeValue'
And then...
SELECT
COUNT(1)
FROM
AEC.gwd_people
LEFT OUTER JOIN AEC.view_iam_r_unitp_building ON AEC.view_iam_r_unitp_building.IDUNITPROD = AEC.gwd_people.cod_sector
LEFT OUTER JOIN AEC.aec_r_workstation_people ON AEC.gwd_people.cod_people = AEC.aec_r_workstation_people.cod_people
WHERE
AEC.gwd_people.PrimaryKeyColumn = 'SomeValue'
Until you see the amount of rows jump up when you don't expect it to. You are most likely:
Not considering that duplicate rows can be expected.
Missing another join column on a table.
Having duplicate rows on a table.
... or combination of these.
Your table design makes it a bit hard to understand their relations. This is what it looks like to me:
gwd_department {1:n} gwd_people
gwd_people {m:n} aec_workstation
gwd_people {m:n} view_iam_r_unitp_building
gwd_people {?:n} gwd_cost_center
So for a person linked to 3 aec_workstations and 4 view_iam_r_unitp_buildings, you'd produce 3 x 4 = 12 result rows. Is there no further relation between an aec_workstation and a view_iam_r_unitp_building? If not, then why do you combine them in your query?
I don't know whether cod_cdc is supposed to be short for cod_cost_center or something different. If this is an m:n relation, too, you are doing the same thing again with gwd_cost_center related to aec_workstation and view_iam_r_unitp_building.
Having said this: Either add the missing criteria or ask yourself what you want to select after all.

Query returning duplicate rows

I wrote this query
SELECT DISTINCT
F2_FILIAL, F2_SERIE, F2_DOC,
C6_NUM, AB7_NUMOS, A1_NOME, F2_EMISSAO, F2_VALBRUT, F2_VEND1,
A3_NOME,F2_COND , E4_DESCRI, C5_NATUREZ, ED_DESCRIC, AAG_DESCRI
FROM
SF2010 SF
LEFT JOIN
SE4010 SE ON F2_COND = E4_CODIGO
LEFT JOIN
SA3010 A3 ON F2_VEND1 = A3_COD
LEFT JOIN
SA1010 A1 ON F2_CLIENTE = A1_COD
LEFT JOIN
SD2010 SD ON F2_DOC = D2_DOC
LEFT JOIN
SC6010 C6 ON D2_PEDIDO = C6_NUM
LEFT JOIN
SC5010 C5 ON D2_PEDIDO = C5_NUM
LEFT JOIN
SED010 ED ON C5_NATUREZ = ED_CODIGO
LEFT JOIN
AB7010 AB ON SUBSTRING(C6_NUMOS,1,6) = AB7_NUMOS
LEFT JOIN
AAG010 AG ON AB7_CODPRB = AAG_CODPRB
WHERE
(F2_CLIENTE >= ' '
AND F2_CLIENTE <= 'zzzzzz')
AND (F2_EMISSAO >= '20170222'
AND F2_EMISSAO <= '20170222')
AND (F2_VEND1 >= ''
AND F2_VEND1 <= 'zz')
AND (C5_NATUREZ >= ''
AND C5_NATUREZ <= 'zzzzzzzzzz')
AND (F2_COND >= ''
AND F2_COND <= 'zzz')
AND (F2_FILIAL >= ''
AND F2_FILIAL <= 'zz')
AND (SF.D_E_L_E_T_ <> '*')
AND F2_DUPL <> ''
AND F2_VALFAT <> 0
ORDER BY
F2_VEND1, F2_EMISSAO
And it results in something like this:
Notice that the 2 last rows are the same (the main field here is F2_DOC, it should never appear twice), but since the field C6_NUM and AB7_NUMOS has more than one reference it displays both of them, duplicating the row.
How can I improve my query to not duplicate a row when the table I'm joining has more than 1 distinct FK to the table I'm querying?
If you are doing multiple left joins and the leftest table in the join doesn't have ( or not mentioned in select ) a unique value, it's possible you get duplicate rows. if you need to have a unique column, use the primary key in the leftest table inside the select statement or add a column like
row_number() as id
to your query.

Problem with Full Outer Join not working as expected

I have a query to subtract current balance from one table with previous balance from another history table. When a particular product has no current balance but has previous balance, I am able to subtract it correctly...in this case it will be like 0 - 100.
However, when the product has current balance but no previous balance, I am unable to get the result. My query does not even select the current balance even though I have done a full outer join on both tables.
Following is my query:
SELECT DATEPART(yyyy, #ExecuteDate) * 10000 + DATEPART(mm, #ExecuteDate) * 100 + DATEPART(dd, #ExecuteDate) AS Period_Key,
CASE WHEN GL.GL_Acct_Key IS NULL THEN 0 ELSE GL.GL_Acct_Key END AS GL_Acct_Key,
CASE WHEN BANK.Bank_Type_Key IS NULL THEN 0 ELSE BANK.Bank_Type_Key END AS Bank_Type_Key,
CASE WHEN TSC.TSC_Key IS NULL THEN 0 ELSE TSC.TSC_Key END AS TSC_Key,
ISNULL(FT.CurrentBalance,0) - ISNULL(HIST.CurrentBalance,0) AS Actual_Income_Daily,
CASE WHEN BR.Branch_Key IS NULL THEN 0 ELSE BR.Branch_Key END AS Branch_Key
FROM WSB_Stage.dbo.Stage_TS_Daily_Income_Hist HIST
FULL OUTER JOIN WSB_Stage.dbo.Stage_TS_Daily_Income FT
ON FT.GLAcctID = HIST.GLAcctID AND
FT.BankType = HIST.BankType AND
FT.BranchNumber = HIST.BranchNumber
LEFT OUTER JOIN WSB_Mart.dbo.Dim_Branch BR
ON HIST.BranchNumber = BR.Branch_Code
LEFT OUTER JOIN WSB_Mart.dbo.Dim_GL_Acct GL
ON HIST.GLAcctID = GL.Acct_Code
LEFT OUTER JOIN WSB_Mart.dbo.Dim_Bank_Type BANK
ON HIST.BankType = BANK.Bank_Type_Code
LEFT OUTER JOIN WSB_Stage.dbo.Param_Branch_TSC_Map BRTSC
ON HIST.BranchNumber = BRTSC.BranchNumber
LEFT OUTER JOIN WSB_Mart.dbo.Dim_TSC TSC
ON BRTSC.RegionCode = TSC.TSC_Code
WHERE HIST.TransactionDate = #PreviousDate
AND GL.Acct_Type_Code = 'Interest'
AND BANK.Bank_Type_Key = 1
You are checking a attribute of the HIST table in the WHERE clause. If there is no entry in the HIST table, the clause doesn't match and thus discards the row.
Replace
WHERE HIST.TransactionDate = #PreviousDate
with
WHERE (HIST.TransactionDate IS NULL OR HIST.TransactionDate = #PreviousDate)
It's because of:
WHERE HIST.TransactionDate = #PreviousDate
This forces Hist.TransactionDate not to be null.
You could use
WHERE (HIST.TransactionDate = #PreviousDate OR HIST.TransactionDate IS NULL)
or change the join to:
FULL OUTER JOIN WSB_Stage.dbo.Stage_TS_Daily_Income FT
ON FT.GLAcctID = HIST.GLAcctID AND
FT.BankType = HIST.BankType AND
FT.BranchNumber = HIST.BranchNumber AND
HIST.TransactionDate = #PreviousDate
Thanks for the help but I couldn't get it to work the way I wanted using the below answers. Finally, I decided to go the long way and declare two temporary tables to hold current and previous balances. I think I want to stay as far away from outer joins as possible ;p
Code is below:
INSERT INTO #PreviousGL
SELECT GLAcctID,
BankType,
BranchNumber,
ISNULL(CurrentBalance,0) AS Current_Balance
FROM WSB_Stage.dbo.Stage_TS_Daily_Income_Hist
WHERE TransactionDate = #PreviousDate
INSERT INTO #CurrentGL
SELECT GLAcctID,
BankType,
BranchNumber,
ISNULL(CurrentBalance,0) AS Current_Balance
FROM WSB_Stage.dbo.Stage_TS_Daily_Income
INSERT INTO #DailyIncomeGL
SELECT CASE WHEN CURR.GLAcctID IS NULL THEN PREV.GLAcctID
WHEN PREV.GLAcctID IS NULL THEN CURR.GLAcctID
WHEN CURR.GLAcctID IS NULL AND PREV.GLAcctID IS NULL THEN 0
ELSE CURR.GLAcctID
END AS GLAcctID,
CASE WHEN CURR.BankType IS NULL THEN PREV.BankType
WHEN PREV.BankType IS NULL THEN CURR.BankType
WHEN CURR.BankType IS NULL AND PREV.BankType IS NULL THEN ''
ELSE CURR.BankType
END AS BankType,
CASE WHEN CURR.BranchNumber IS NULL THEN PREV.BranchNumber
WHEN PREV.BranchNumber IS NULL THEN CURR.BranchNumber
WHEN CURR.BranchNumber IS NULL AND PREV.BranchNumber IS NULL THEN 0
ELSE CURR.BranchNumber
END AS BranchNumber,
ISNULL(CURR.CurrentBal,0) - ISNULL(PREV.CurrentBal,0) AS Actual_Income_Daily
FROM #CurrentGL CURR
FULL OUTER JOIN #PreviousGL PREV
ON CURR.GLAcctID = PREV.GLAcctID AND
CURR.BankType = PREV.BankType AND
CURR.BranchNumber = PREV.BranchNumber