How to use left join to take all data from master table? - sql

How can i take all data from EmniyetStok. For example EmniyetStok has 1000 rows and maching other table 200 rows. Below query returns to me 200 rows. But i wanna take all emniyetstok (all 1000 rows) . I used left join (for EmniyetStok) but it dows not work. i wanna take all rows of Emniyetstok (master table). if t.Quantity is null or or empty, at the end of the query exeqution , it should be zero.
please dont remove: WHERE {0} clouse i need after. after where , it should return 1000 rows. "WHERE e.CustomerID = '0061004287' AND t.SapContractNumber = '3120012161' " i will add.
SELECT
s.MaterialNumber,
sum(s.Stock) Stock,
dbo.getSapContractNumberBySapDeliveryNumber(s.SapDeliveryNumber) SapContractNumber,
s.BillTo,
s.Quantity
INTO #tmp
FROM Stok s
GROUP BY s.MaterialNumber, s.SapDeliveryNumber, s.BillTo, s.Quantity
-----------------------
-----------------------
SELECT
e.SapContractNumber [Anlaşma No],
c.ContractName [Anlaşma Adı],
e.CustomerId [Müşteri No],
cu.CustomerFullName [Müşteri Adı],
e.MaterialNumber [Ürün No],
sc.MaterialName [Ürün],
convert(decimal(10,2),avg(EmniyetStok)) [Emniyet Stok],
convert(decimal(10,2),avg(OrtalamaStok)) [OrtalamaStok],
convert(decimal(10,2),sum(Stock)) Stok,
convert(decimal(10,2),avg(e.ortalamastok) - sum(t.Quantity)) SiparisOnerisi
FROM EmniyetStok e
LEFT JOIN #tmp t
ON t.MaterialNumber = e.MaterialNumber
AND t.SapContractNumber = e.SapContractNumber
AND e.CustomerID = t.BillTo
LEFT JOIN Contracts c ON c.SAPContractNumber = e.SapContractNumber
LEFT JOIN Customers cu ON cu.CustomerID = e.CustomerID
LEFT JOIN StockCards sc ON sc.MaterialNumber = e.MaterialNumber
WHERE {0}
GROUP BY
e.SapContractNumber,
c.ContractName,
e.CustomerId,
cu.CustomerFullName,
e.MaterialNumber,
sc.MaterialName
HAVING sum(t.Quantity) < avg(e.ortalamastok)
DROP TABLE #tmp

Your problem is in the string:
HAVING sum(t.Quantity) < avg(e.ortalamastok)
You lose records when t.Quantity is null or e.ortalamastok is null.
Сorrect and check:
HAVING sum(ISNULL(t.Quantity, 0)) < avg(ISNULL(e.ortalamastok,0))

Related

Sql Joining 3 Tables Query for Loan Total Result

I have to get the total of Customer Loan from 3 tables the two tables are given loan to sum and the other subtract the paid amount and the tables have Customer ID in common. so far I can get the result only if the Customer ID exist in all tables but if it doesn't exist in one table I won't get Customer in my result. or I get NULL customer IDs when I anchor to the customer.
SELECT
AS1.C_ID AS [Customer ID],
ISNULL(AS1.OldCustomerLoan, 0) AS [Old Loan],
ISNULL(AS2.NewGivenLoan, 0) AS [New Given Loan],
ISNULL(AS3.LoanPaid, 0) AS [PaidLoanAmount],
(ISNULL(AS1.OldCustomerLoan, 0) +
ISNULL(AS2.NewGivenLoan, 0) -
ISNULL(AS3.LoanPaid,0) ) AS Total
FROM
Customer C
LEFT OUTER JOIN
(SELECT
MOC.C_ID,
SUM(MOC.Quantity) AS OldCustomerLoan
FROM
Money_On_Customer MOC (NOLOCK)
GROUP BY
MOC.C_ID) AS1
ON c.C_Id = AS1.C_Id
LEFT OUTER JOIN
(SELECT
NGL.C_ID
,SUM(NGL.G_Take_Loan) AS NewGivenLoan
FROM
Given_Loan NGL
GROUP BY
NGL.C_ID) AS2
ON c.C_Id = AS2.C_Id
LEFT OUTER JOIN
(SELECT
GLP.C_ID, SUM(GLP.G_P_Loan) AS LoanPaid
FROM
Given_Loan_Paid GLP
GROUP BY
GLP.C_ID ) AS3
ON c.C_Id = AS3.C_Id
Here Is a picture of my two results:
When I get NULL Customer IDs
When I don't get All the Customers
You need to use c.c_id for the first column
In order to only get records where they exist in at least one of the tables you can add this to you query, just put you current query in place of the dots, and add the leftid col
Select *
From
(Select c.c_id custonerid,
Coalesce(Coalesce(as1.c_id,as2.c_id),as3.c_id) leftid,......
From ....
) ilv
Where leftid is not null
You might be able to just add
Where coalesce(coalesce(as1.c_id,as2.c_id),as3.c_id) is not null
To then end of your query
#Ab Bennett's answer is right,
because you should use your main(master) table's primary key column
if Customer ID is not available in as1 (Money_On_Customer) it will show null.
Hope you understand my explanation.
UPDATE:
and use following for getting customer id
COALESCE(c.C_Id, AS1.C_Id, AS2.C_Id)
you will get first not null Customer ID
Here is My answer with the help of #Ab Bennett
Select *
From
(
SELECT
C.C_Name AS [Customer ID],
ISNULL(AS1.OldCustomerLoan, 0) AS [Old Loan],
ISNULL(AS2.NewGivenLoan, 0) AS [New Given Loan],
ISNULL(AS3.LoanPaid, 0) AS [PaidLoanAmount],
(ISNULL(AS1.OldCustomerLoan, 0) +
ISNULL(AS2.NewGivenLoan, 0) -
ISNULL(AS3.LoanPaid,0) ) AS Total
FROM
Customer C
LEFT OUTER JOIN
(SELECT
MOC.C_ID,
SUM(MOC.Quantity) AS OldCustomerLoan
FROM
Money_On_Customer MOC (NOLOCK)
GROUP BY
MOC.C_ID) AS1
ON c.C_Id = AS1.C_Id
LEFT OUTER JOIN
(SELECT
NGL.C_ID
,SUM(NGL.G_Take_Loan) AS NewGivenLoan
FROM
Given_Loan NGL
GROUP BY
NGL.C_ID) AS2
ON c.C_Id = AS2.C_Id
LEFT OUTER JOIN
(SELECT
GLP.C_ID, SUM(GLP.G_P_Loan) AS LoanPaid
FROM
Given_Loan_Paid GLP
GROUP BY
GLP.C_ID ) AS3
ON c.C_Id = AS3.C_Id) ilv
Where not ([Old Loan] = 0 and [New Given Loan]=0 and PaidLoanAmount =0 )

SQL statement merge two rows into one

In the results of my sql-statement (SQL Server 2016) I would like to combine two rows with the same value in two columns ("study_id" and "study_start") into one row and keep the row with higest value in a third cell ("Id"). If any columns (i.e. "App_id" or "Date_arrival) in the row with higest Id is NULL, then it should take the value from the row with the lowest "Id".
I get the result below:
Id study_id study_start Code Expl Desc Startmonth App_id Date_arrival Efter_op Date_begin
167262 878899 954 4.1 udd.ord Afbrudt feb 86666 21-06-2012 N 17-08-2012
180537 878899 954 1 Afsluttet Afsluttet feb NULL NULL NULL NULL
And I would like to get this result:
Id study_id study_start Code Expl Desc Startmonth App_id Date_arrival Efter_op Date_begin
180537 878899 954 1 Afsluttet Afsluttet feb 86666 21-06-2012 N 17-08-2012
My statement looks like this:
SELECT dbo.PopulationStam_V.ELEV_ID AS id,
dbo.PopulationStam_V.PERS_ID AS study_id,
dbo.STUDIESTARTER.STUDST_ID AS study_start,
dbo.Optagelse_Studiestatus.AFGANGSARSAG AS Code,
dbo.Optagelse_Studiestatus.KORT_BETEGNELSE AS Expl,
ISNULL((CAST(dbo.Optagelse_Studiestatus.Studiestatus AS varchar(20))), 'Indskrevet') AS 'Desc',
dbo.STUDIESTARTER.OPTAG_START_MANED AS Startmonth,
dbo.ANSOGNINGER.ANSOG_ID as App_id,
dbo.ANSOGNINGER.ANKOMSTDATO AS Data_arrival',
dbo.ANSOGNINGER.EFTEROPTAG AS Efter_op,
dbo.ANSOGNINGER.STATUSDATO AS Date_begin
FROM dbo.INSTITUTIONER
INNER JOIN dbo.PopulationStam_V
ON dbo.INSTITUTIONER.INST_ID = dbo.PopulationStam_V.SEMI_ID
LEFT JOIN dbo.ANSOGNINGER
ON dbo.PopulationStam_V.ELEV_ID = dbo.ANSOGNINGER.ELEV_ID
INNER JOIN dbo.STUDIESTARTER
ON dbo.PopulationStam_V.STUDST_ID_OPRINDELIG = dbo.STUDIESTARTER.STUDST_ID
INNER JOIN dbo.UDD_NAVNE_T
ON dbo.PopulationStam_V.UDDA_ID = dbo.UDD_NAVNE_T.UDD_ID
INNER JOIN dbo.UDDANNELSER
ON dbo.UDD_NAVNE_T.UDD_ID = dbo.UDDANNELSER.UDDA_ID
LEFT OUTER JOIN dbo.PERSONER
ON dbo.PopulationStam_V.PERS_ID = dbo.PERSONER.PERS_ID
LEFT OUTER JOIN dbo.POSTNR
ON dbo.PERSONER.PONR_ID = dbo.POSTNR.PONR_ID
LEFT OUTER JOIN dbo.KønAlleElevID_V
ON dbo.PopulationStam_V.ELEV_ID = dbo.KønAlleElevID_V.ELEV_ID
LEFT OUTER JOIN dbo.Optagelse_Studiestatus
ON dbo.PopulationStam_V.AFAR_ID = dbo.Optagelse_Studiestatus.AFAR_ID
LEFT OUTER JOIN dbo.frafaldsmodel_adgangsgrundlag
ON dbo.frafaldsmodel_adgangsgrundlag.ELEV_ID = dbo.PopulationStam_V.ELEV_ID
LEFT OUTER JOIN dbo.Optagelse_prioriteterUFM
ON dbo.Optagelse_prioriteterUFM.cpr = dbo.PopulationStam_V.CPR_NR
AND dbo.Optagelse_prioriteterUFM.Aar = dbo.frafaldsmodel_adgangsgrundlag.optagelsesaar
LEFT OUTER JOIN dbo.frafaldsmodel_stoettetabel_uddannelser AS fsu
ON fsu.id_uddannelse = dbo.UDDANNELSER.UDDA_ID
AND fsu.id_inst = dbo.INSTITUTIONER.INST_ID
AND fsu.uddannelse_aar = dbo.frafaldsmodel_adgangsgrundlag.optagelsesaar
WHERE dbo.STUDIESTARTER.STUDIESTARTSDATO > '2012-03-01 00:00:00.000'
AND (dbo.Optagelse_Studiestatus.AFGANGSARSAG IS NULL
OR dbo.Optagelse_Studiestatus.AFGANGSARSAG NOT LIKE '2.7.4')
AND (dbo.PopulationStam_V.INDSKRIVNINGSFORM = '1100'
OR dbo.PopulationStam_V.INDSKRIVNINGSFORM = '1700')
GROUP BY dbo.PopulationStam_V.ELEV_ID,
dbo.PopulationStam_V.PERS_ID,
dbo.STUDIESTARTER.STUDST_ID,
dbo.Optagelse_Studiestatus.AFGANGSARSAG,
dbo.Optagelse_Studiestatus.KORT_BETEGNELSE,
dbo.STUDIESTARTER.OPTAG_START_MANED,
Studiestatus,
dbo.ANSOGNINGER.ANSOG_ID,
dbo.ANSOGNINGER.ANKOMSTDATO,
dbo.ANSOGNINGER.EFTEROPTAG,
dbo.ANSOGNINGER.STATUSDATO
I really hope somebody out there can help.
Many ways, this will work:
WITH subSource AS (
/* Your query here */
)
SELECT
s1.id,
/* all other columns work like this:
COALESCE(S1.column,s2.column)
for example: */
coalesce(s1.appid,s2.appid) as appid
FROM subSource s1
INNER JOIN subSource s2
ON s1.study_id =s2.study_id
and s1.study_start = s2.study_start
AND s1.id > s2.id
/* I imagine some other clauses might be needed but maybe not */
The rest is copy paste

SQL - Only show results for one column in first instance of a duplicated record

I am finding it difficult to explain exactly what I am trying to achieve so I think it best to show a visual representation.
Example of how my query results currently look
Example of how I want the results to look
The report I am running shows a list of every product within orders. Each product has its own cost assigned to it. Another column is a delivery charge, but this is a charge assigned to the order; not individual products. I want to be able to show the delivery charge against the first product in each order ONLY.
I have attempted, for far too long, to try and find an answer to this query but have had no luck. I don't know if it is even possible so assistance of any sort, or even just being pointed in the right direction, would be of great help.
Thanks
EDIT.
If it helps here is my query:
SELECT dbo.Orders.EncryptedOrderId,
dbo.OrderProduct.ProductID,
dbo.OrderProduct.QuantityPerRecipient,
dbo.OrderProduct.NumRecipients,
dbo.OrderProduct.TotalQuantity,
dbo.DocType.Name AS [Product Type],
dbo.ProductGroup_Culture.Name AS [Product Group],
RIGHT(CatalogNo, CHARINDEX('_', REVERSE('_' + CatalogNo)) -1) AS [HamptonsType],
FORMAT(dbo.Orders.DateOrderCreated, 'dd/MM/yyyy HH:mm:ss') AS 'DateOrderCreated',
CAST(REPLACE(dbo.Orders.ClearingResult, 'utf-8', 'utf-16') AS XML ).value('(/UserData//CostCenter/node())[1]', 'nvarchar(max)') AS [Cost Center],
dbo.Users.FirstName,
dbo.Users.LastName,
dbo.Users.CompanyName AS [Branch Name],
dbo.Users.Department AS Subsidiary,
dbo.Users.Custom1,
dbo.Users.Custom2,
dbo.Users.Custom3,
dbo.Users.Custom4,
dbo.Users.Custom5,
dbo.OrderProduct.TotalPrice,
dbo.Orders.ShippingCharges,
dbo.OrderProduct.OrderProductID,
dbo.FileSubmissionDocument.OriginalFileType,
COALESCE (dbo.FileSubmissionDocument.Title, dbo.Product_Culture.Name) AS [Product Name],
OPDV.FriendlyValue AS 'BCard Recipient'
FROM dbo.DocType
INNER JOIN dbo.Doc
ON dbo.DocType.DocTypeID = dbo.Doc.DocTypeID
INNER JOIN dbo.OrderProduct
ON dbo.Doc.ProductID = dbo.OrderProduct.ProductID
LEFT JOIN dbo.Product
ON dbo.Product.ProductID = dbo.Doc.ProductID
LEFT JOIN dbo.ProductGroupMembership
ON dbo.ProductGroupMembership.ProductID = dbo.Doc.ProductID
LEFT JOIN dbo.ProductGroup_Culture
ON dbo.ProductGroup_Culture.ProductGroupID = dbo.ProductGroupMembership.ProductGroupID
INNER JOIN dbo.Orders
ON dbo.OrderProduct.OrderID = dbo.Orders.OrderID
INNER JOIN dbo.Users
ON dbo.Orders.UserID = dbo.Users.UserID
INNER JOIN dbo.Product_Culture
ON dbo.OrderProduct.ProductID = dbo.Product_Culture.ProductID
INNER JOIN dbo.Store_Culture
ON dbo.Store_Culture.StoreID = dbo.Users.AssignedToStoreID FULL OUTER
JOIN dbo.FileSubmissionDocument
ON dbo.OrderProduct.OrderProductID = dbo.FileSubmissionDocument.SubOrderProductID - 1
LEFT JOIN (SELECT OP.OrderProductID,
OP.DialID,
OP.FriendlyValue
FROM OrderProductDialValue OP
LEFT JOIN Dial DI ON DI.DialID = OP.DialID
LEFT JOIN OrderProduct OT ON OT.OrderProductID = OP.OrderProductID
LEFT JOIN Product PR ON PR.ProductID = OT.ProductID
WHERE PR.ExternalID = 'BCName'
AND DI.UProduceDialName = 'Name') OPDV ON OPDV.OrderProductID = dbo.OrderProduct.OrderProductID
WHERE ('#CUSTOMERNAME' is null
OR '#CUSTOMERNAME' = ''
OR dbo.Store_Culture.Name LIKE '%' + '#CUSTOMERNAME' + '%')
AND dbo.OrderProduct.IsDraft = 0
AND dbo.Orders.IsCart=0
AND dbo.Orders.IsSaveForLater=0
AND (('#DATE' <= dbo.Orders.DateOrderCreated)
OR ('#DATE' IS NULL)
OR ('#DATE'=''))
AND ((DATEADD(day, 1, '#DATE') >= dbo.Orders.DateOrderCreated)
OR ('#DATE' IS NULL)
OR ('#DATE'=''))
AND dbo.Users.LastName NOT LIKE '%TEST%'
ORDER BY dbo.Orders.OrderID DESC, dbo.OrderProduct.OrderProductID DESC
The query runs through a reporting system on an online portal so the values that show as #CUSTOMERNAME or #DATE are variables based on values given at the time when the report is run.
this may help you
select orderid,
productid,
productvalue,
case ROW_NUMBER() over (partition by orderid order by orderid)
when 1 then deliverycharge
else null end as 'deliverycharge'
from ........
I assume your query looks like
select orderID
, productID
, productValue
, DeliveryCharge
from test_t
order by orderID
, productValue desc
;
and that you want delivery charges listed for the most expensive product of each order.
If supported by your rdbms, you can use the analytic RANK function
select orderID
, productID
, productValue
, DeliveryCharge
, CASE RANK() OVER ( PARTITION BY orderID ORDER BY productValue DESC ) WHEN 1 THEN DeliveryCharge ELSE NULL END r
from test_t
order by orderID
, productValue desc
;
If your rdbms does not support RANK, you can emulate it using a left join with a suitably aggregated copy of your table:
select t.orderID
, t.productID
, t.productValue
, rt.mdc DeliveryCharge
from test_t t
left join (
select orderID
, max(productValue) mp
, max(DeliveryCharge) mdc
from test_t
group by orderID
) rt
on (
rt.orderID = t.orderID
AND rt.mp = t.productValue
)
order by orderID
, productValue desc
;
The tacit assumption is that the delivery charge is by order (which seems reasonable as you wouldn't want to selectively drop it otherwise, right ?).
Moreover, both solutions will produce multiple rows containing the delivery charge per order if that order contains multipleproducts with the same productValue.
Tested on oracle 12c1;

returning only the most recent record in dataset

I have a query returning data for several dates.
I want to return only record with the most recent date in the field SAPOD (the date is in fact CYYMMDD where C=0 before 2000 and 1 after 2000 and I can show this as YYYYMMDD using SAPOD=Case when LEFT(SAPOD,1)=1 then '20' else '19' end + SUBSTRING(cast(sapod as nvarchar(7)),2,7))
here is my query:
SELECT GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,CUS.GFCUN, BGCFN1,
BGCFN2, BGCFN3, SV.SVCSA, SV.SVNA1, SV.SVNA2, SV.SVNA3,
SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
FROM SCPF ACC
INNER JOIN GFPF CUS ON GFCPNC = SCAN
LEFT OUTER JOIN SXPF SEQ ON SXCUS = GFCUS AND SXPRIM = ''
LEFT OUTER JOIN SVPFClean SV ON SVSEQ = SXSEQ
LEFT OUTER JOIN BGPF ON BGCUS = GFCUS AND BGCLC = GFCLC
LEFT OUTER JOIN NEPF NE ON SCAB=NE.NEAB and SCAN=ne.NEAN and SCAS=ne.NEAS
LEFT OUTER JOIN SAPF SA ON SCAB=SAAB and SCAN=SAAN and SCAS=SAAS
WHERE
(SATCD>500 and
scsac='IV' and
scbal = 0 and
scai30<>'Y' and
scai14<>'Y' and
not exists(select * from v5pf where v5and=scan and v5bal<>0))
GROUP BY GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,
CUS.GFCUN, BGCFN1, BGCFN2, BGCFN3, SV.SVCSA,
SV.SVNA1, SV.SVNA2, SV.SVNA3, SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
ORDER BY MAX(SCAN) ASC, SAPOD DESC
I am getting results like the below where there are several transactions by a customer, and we only want to show the data of the most recent transaction:
So how can I show just the most recent transaction? Is this a case where I should use an OUTER APPLY or CROSS APPY?
EDIT:
Sorry I should clarify that I need the most recent date for each of the unique records in the field NEEAN which is the Account number
You can use ROW_NUMBER() as follows:
SELECT
ROW_NUMBER() OVER (PARTITION BY Ne.NEEAN ORDER BY SAPOD DESC) AS [Row],
GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,CUS.GFCUN, BGCFN1,
BGCFN2, BGCFN3, SV.SVCSA, SV.SVNA1, SV.SVNA2, SV.SVNA3,
SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
FROM SCPF ACC
INNER JOIN GFPF CUS ON GFCPNC = SCAN
LEFT OUTER JOIN SXPF SEQ ON SXCUS = GFCUS AND SXPRIM = ''
LEFT OUTER JOIN SVPFClean SV ON SVSEQ = SXSEQ
LEFT OUTER JOIN BGPF ON BGCUS = GFCUS AND BGCLC = GFCLC
LEFT OUTER JOIN NEPF NE ON SCAB=NE.NEAB and SCAN=ne.NEAN and SCAS=ne.NEAS
LEFT OUTER JOIN SAPF SA ON SCAB=SAAB and SCAN=SAAN and SCAS=SAAS
WHERE
(SATCD>500 and
scsac='IV' and
scbal = 0 and
scai30<>'Y' and
scai14<>'Y' and
not exists(select * from v5pf where v5and=scan and v5bal<>0)) and
[Row] = 1
GROUP BY GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,
CUS.GFCUN, BGCFN1, BGCFN2, BGCFN3, SV.SVCSA,
SV.SVNA1, SV.SVNA2, SV.SVNA3, SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
ORDER BY MAX(SCAN) ASC
You could encapsulate this within a subquery if you don't want to return the [Row] column.
you can user row_number to get top 1 row per customer
In the where clause need to return values with pos value as 1
sample query
row_number() over ( partition by GFCUS order by SAPOD desc) as pos

Showing all values in Group By with inclusion of CASE

I have the following data
CREATE TABLE #Test
(
Severity NVARCHAR(50)
,WorkId INT
)
INSERT INTO #Test VALUES('High',1)
INSERT INTO #Test VALUES('Critical',2)
SELECT
CASE
WHEN Severity IN ('High','Critical') THEN 'Critical'
WHEN Severity IN ('Low','Medium') THEN 'Medium'
END AS 'Severity'
,COUNT(*) AS 'Total'
FROM #Test
GROUP BY
CASE
WHEN Severity IN ('High','Critical') THEN 'Critical'
WHEN Severity IN ('Low','Medium') THEN 'Medium'
END
This results in output -
Severity | Total
---------+-------
Critical | 2
I am expecting the following output -
Severity | Total
---------+-------
Critical | 2
Medium | 0
I have looked into the following two links which details a similar case but not same and am still unable to get the result -
http://ask.sqlservercentral.com/questions/47705/showing-null-values-as-well-in-group-by-in-sql.html
How to return empty groups in SQL GROUP BY clause
Any help or links?
Further update.
Having tried the solution below, the results are still not appearing. Pasting here the actual code wherein I would need to apply the logic
SELECT s.NewSeverity AS 'Severity'
,COUNT(WI.microsoft_vsts_common_severity) AS 'Total'
FROM ( VALUES
('Critical','I-High')
,('High','I-High')
,('Medium','I-Low')
,('Low','I-Low')
)s(OldSeverity,NewSeverity)
LEFT JOIN DimWorkItem WI (NOLOCK)
ON WI.microsoft_vsts_common_severity = s.OldSeverity
JOIN dbo.DimPerson P
ON p.personsk = WI.system_assignedto__personsk
JOIN DimTeamProject TP
ON WI.TeamProjectSK = TP.ProjectNodeSK
JOIN DimIteration Itr (NOLOCK)
ON Itr.IterationSK = WI.IterationSK
JOIN DimArea Ar (NOLOCK)
ON Ar.AreaSK = WI.AreaSK
WHERE TP.ProjectNodeName = 'ABC'
AND WI.System_WorkItemType = 'Bug'
AND WI.Microsoft_VSTS_CMMI_RootCause <> 'Change Request'
AND Itr.IterationPath LIKE '%\ABC\R1234\Test\IT%'
AND WI.System_State NOT IN ( 'Rejected', 'Closed' )
AND WI.System_RevisedDate = CONVERT(datetime, '9999', 126)
GROUP BY s.NewSeverity
In actual there are only two 'Low' items, hence the output I am getting is I-Low, 2 whereas I want even I-High to appear with 0 count.
The way I would go about this is to create your own table of values using a table value constructor:
SELECT OldSeverity, NewSeverity
FROM (VALUES
('Critical', 'Critical'),
('High', 'Critical'),
('Medium', 'Medium'),
('Low', 'Medium')
) s (OldSeverity, NewSeverity);
This gives a table you can select from, then left join to your existing table:
SELECT Severity = s.NewSeverity,
Total = COUNT(t.Severity)
FROM (VALUES
('Critical', 'Critical'),
('High', 'Critical'),
('Medium', 'Medium'),
('Low', 'Medium')
) s (OldSeverity, NewSeverity)
LEFT JOIN #Test t
ON t.Severity = s.OldSeverity
GROUP BY s.NewSeverity;
This will give the desired results.
Example on SQL Fiddle
EDIT
The problem you have with the way that you are implimenting the query, is that although you have immediately left joined to DimWorkItem you then inner join to subsequent tables and refer to columns in WorkItem in the where clause, which undoes your left join and turns it back into an inner join. You need to place your whole logic into a subquery, and left join to this:
SELECT s.NewSeverity AS 'Severity'
,COUNT(WI.microsoft_vsts_common_severity) AS 'Total'
FROM ( VALUES
('Critical','I-High')
,('High','I-High')
,('Medium','I-Low')
,('Low','I-Low')
)s(OldSeverity,NewSeverity)
LEFT JOIN
( SELECT wi.Severity
FROM DimWorkItem WI (NOLOCK)
JOIN dbo.DimPerson P
ON p.personsk = WI.system_assignedto__personsk
JOIN DimTeamProject TP
ON WI.TeamProjectSK = TP.ProjectNodeSK
JOIN DimIteration Itr (NOLOCK)
ON Itr.IterationSK = WI.IterationSK
JOIN DimArea Ar (NOLOCK)
ON Ar.AreaSK = WI.AreaSK
WHERE TP.ProjectNodeName = 'ABC'
AND WI.System_WorkItemType = 'Bug'
AND WI.Microsoft_VSTS_CMMI_RootCause <> 'Change Request'
AND Itr.IterationPath LIKE '%\ABC\R1234\Test\IT%'
AND WI.System_State NOT IN ( 'Rejected', 'Closed' )
AND WI.System_RevisedDate = CONVERT(datetime, '9999', 126)
) WI
ON WI.Severity = s.OldSeverity
GROUP BY s.NewSeverity;