piedpiper11
piedpiper11

Reputation: 3

SQL query not returning Null-value records

I am using SQL Server 2014 on a Windows 10 PC. I am sending SQL queries directly into Swiftpage’s Act! CRM system (via Topline Dash). I am trying to figure out how to get the query to give me records even when some of the records have certain Null values in the Opportunity_Name field.

I am using a series of Join statements in the query to connect 4 tables: History, Contacts, Opportunity, and Groups. History is positioned at the “center” of it all. They all have many-to-many relationships with each other, and are thus each linked by an intermediate table that sits “between” the main tables, like so:

History – Group_History – Group
History – Contact_History – Contact
History – Opportunity_History – Opportunity

The intermediate tables consist only of the PKs in each of the main tables. E.g. History_Group is only a listing of HistoryIDs and GroupIDs. Thus, any given History entry can have multiple Groups, and each Group has many Histories associated with it.

Here’s what the whole SQL statement looks like:

SELECT Group_Name, Opportunity_Name, Start_Date_Time, Contact.Contact, Contact.Company, History_Type, (SQRT(SQUARE(Duration))/60) AS Hours, Regarding, HistoryID
FROM HISTORY
   JOIN Group_History
       ON Group_History.HistoryID = History.HistoryID
   JOIN "Group"
       ON Group_History.GroupID = "Group".GroupID
   JOIN Contact_History
       ON Contact_History.HistoryID = History.HistoryID
   JOIN Contact
       ON Contact_History.ContactID = Contact.ContactID
   JOIN Opportunity_History
       ON Opportunity_History.HistoryID = History.HistoryID
   JOIN Opportunity
       ON Opportunity_History.OpportunityID = Opportunity.OpportunityID
WHERE
       (  Start_Date_Time >= ('2018/02/02')       AND
          Start_Date_Time <= ('2018/02/16')                )
ORDER BY Group_NAME, START_DATE_TIME;

The problem is that when the Opportunity table is linked in, any record that has no Opportunity (i.e. a Null value) won’t show up. If you remove the Opportunity references in the Join statement, the listing will show all history events in the Date range just fine, the way I want it, whether or not they have an Opportunity associated with them.

I tried adding the following to the WHERE part of the statement, and it did not work.

  AND  (  ISNULL(Opportunity_Name, 'x') = 'x'     OR
          ISNULL(Opportunity_Name, 'x') <> 'x'              )

I also tried changing the Opportunity_Name reference up in the SELECT part of the statement to read: ISNULL(Opportunity_Name, 'x') – this didn’t work either.

Can anyone suggest a way to get the listing to contain all records regardless of whether they have a Null value in the Opportunity Name or not? Many thanks!!!

Upvotes: 0

Views: 127

Answers (2)

Andrew P Smith
Andrew P Smith

Reputation: 11

You will want to make sure you are using a LEFT JOIN with the table Opportunity. This will keep records that do not relate to records in the Opportunity table.

Also, BE CAREFUL you do not filter records using the WHERE clause for the Opportunity table being LEFT JOINED. Include those filter conditions relating to Opportunity instead in the LEFT JOIN ... ON clause.

Upvotes: 1

nbot
nbot

Reputation: 184

I believe this is because a default JOIN statement discards unmatched rows from both tables. You can fix this by using LEFT JOIN.

Example:

CREATE TABLE dataframe (
A int,
B int
);

insert into dataframe (A,B) values 
(1, null),
(null, 1)

select a.A from dataframe a
join dataframe b ON a.A = b.A

select a.A from dataframe a
left join dataframe b ON a.A = b.A

You can see that the first query returns only 1 record, while the second returns both.

SELECT Group_Name, Opportunity_Name, Start_Date_Time, Contact.Contact, Contact.Company, History_Type, (SQRT(SQUARE(Duration))/60) AS Hours, Regarding, HistoryID
FROM HISTORY
   LEFT JOIN Group_History
       ON Group_History.HistoryID = History.HistoryID
   LEFT JOIN "Group"
       ON Group_History.GroupID = "Group".GroupID
   LEFT JOIN Contact_History
       ON Contact_History.HistoryID = History.HistoryID
   LEFT JOIN Contact
       ON Contact_History.ContactID = Contact.ContactID
   LEFT JOIN Opportunity_History
       ON Opportunity_History.HistoryID = History.HistoryID
   LEFT JOIN Opportunity
       ON Opportunity_History.OpportunityID = Opportunity.OpportunityID
WHERE
       (  Start_Date_Time >= ('2018/02/02')       AND
          Start_Date_Time <= ('2018/02/16')                )
ORDER BY Group_NAME, START_DATE_TIME;

Upvotes: 1

Related Questions