简体   繁体   中英

left join not returning NULL values

I'm sure this is due to the fact that I don't know how to use LEFT JOIN, but I'm writing a query that is not returning NULL values. Here's the query:

CREATE TABLE #OrgMaster
(OrgName nvarchar(100))

INSERT INTO #OrgMaster (OrgName)
SELECT DISTINCT Organization
FROM StageReleaseCalendar_VW

SELECT SRC.Organization
, SRC.deploytype
, COUNT(SRC.deploytype) AS 'Deployment Count'
, DATEPART(m,SRC.actualstarttime) AS 'MonthNum'
, DATENAME(m,SRC.actualstarttime) AS 'MonthNam'
 FROM #OrgMaster TTOM LEFT OUTER JOIN StageReleaseCalendar_VW SRC 
 ON LEFT(TTOM.OrgName, LEN(TTOM.OrgName)) = SRC.Organization
WHERE DATEDIFF(m, SRC.scheduledstarttime, CURRENT_TIMESTAMP) BETWEEN 1 AND 2
AND completerelease = 1
AND deploytype IN ('Service Pack','Hot Fix')
AND cancelled = 0
GROUP BY SRC.Organization, SRC.deploytype,  DATEPART(m,SRC.actualstarttime), DATENAME(m,SRC.actualstarttime)

DROP TABLE #OrgMaster

There are four organizations total: Commercial, Consumer, Partner, and Sales. After creating the temp table, if I then run the following query:

SELECT OrgName FROM #OrgMaster

The results are as follows:

Commercial Consumer Partner Sales

Partner has no deployments of any kind in July or August, so what I'm trying to get is a set of results that includes four NULL records for Partner - a record for hotfixes in July, for hotfixes in August, for service packs in July, and for service packs in August. Instead, I get a result set that is limited to only those entries for which a deployment did in fact take place.

Can anyone see what I'm not understanding here?

Thanks.

The problem is your where clause limits data by fields in your (right) table. This will not give you the nulls. To do this, I often encase my SELECT inside another SELECT (nested), so I can then query for nulls in the (right) table.

SELECT * FROM (
SELECT a.ID as AID, b.ID as BID from TableA a
LEFT JOIN TableB b
On ....
WHERE ...
) tmp Where BID is null

The proper query

SELECT TTOM.OrgName 
, SRC.deploytype
, COUNT(SRC.deploytype) AS 'Deployment Count'
, DATEPART(m,SRC.actualstarttime) AS 'MonthNum'
, DATENAME(m,SRC.actualstarttime) AS 'MonthNam'
 FROM #OrgMaster TTOM LEFT OUTER JOIN StageReleaseCalendar_VW SRC 
 ON LEFT(TTOM.OrgName, LEN(TTOM.OrgName)) = SRC.Organization
WHERE SRC.Organization is null or 
 DATEDIFF(m, SRC.scheduledstarttime, CURRENT_TIMESTAMP) BETWEEN 1 AND 2
AND deploytype IN ('Service Pack','Hot Fix')
AND completerelease = 1
AND cancelled = 0
GROUP BY TTOM.OrgName, SRC.deploytype,  DATEPART(m,SRC.actualstarttime), DATENAME(m,SRC.actualstarttime)

Another option would be to guard all the fields from SCR table in WHERE clause with ISNULL operator.

This will work for you. Plus, I think you can use this to get other good information as well.

DECLARE @OrgMaster as table(OrgName nvarchar(100),deptype nvarchar(100),MonthNum int,DeploymentCount int)
DECLARE @Loop1 int
DECLARE @Loop2 int

SELECT @Loop1 = 0, @Loop2 = 0

WHILE @Loop1 <> 2
BEGIN
    SELECT @Loop1 = @Loop1 + 1, @Loop2 = 0

    WHILE @Loop2 <> 2
    BEGIN
        SET @Loop2 = @loop2 + 1

        INSERT INTO @OrgMaster (OrgName,deptype,MonthNum)
        SELECT DISTINCT 
            Organization
            ,CASE WHEN @Loop1 = 1 THEN 'Service Pack' ELSE 'Hot Fix' END
            ,DATEPART(m,DATEADD(MONTH, -1 * @Loop2, GETDATE()))
        FROM StageReleaseCalendar_VW

    END
END


UPDATE @OrgMaster SET
    DeploymentCount = (SELECT COUNT(*) 
                        FROM StageReleaseCalendar_VW 
                        WHERE Organization = OrgName
                            AND deploytype = deptype
                            AND DATEPART(m,actualstarttime) = MonthNum
                            )

SELECT * from @OrgMaster where DeploymentCount = 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM