SQL 查询未返回空值记录

SQL query not returning Null-value records

我在 Windows 10 PC 上使用 SQL Server 2014。我正在向 Swiftpage 的 Act 直接发送 SQL 查询! CRM 系统(通过 Topline Dash)。我试图弄清楚如何让查询给我记录,即使某些记录在 Opportunity_Name 字段中具有某些 Null 值。

我在查询中使用一系列连接语句来连接 4 tables:历史记录、联系人、机会和组。历史处于这一切的“中心”。它们彼此之间都是多对多关系,因此每个都由位于主要 table“之间”的中间 table 链接,如下所示:

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

中间 tables 仅包含每个主要 tables 中的 PK。例如。 History_Group 只是 HistoryID 和 GroupID 的列表。因此,任何给定的历史记录条目都可以有多个组,每个组都有许多与之关联的历史记录。

这是整个 SQL 语句的样子:

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;

问题是,当链接机会 table 时,任何没有机会(即空值)的记录都不会显示。如果您删除 Join 语句中的 Opportunity 引用,列表将以我想要的方式显示日期范围内的所有历史事件,无论它们是否具有与之关联的 Opportunity。

我尝试将以下内容添加到语句的 WHERE 部分,但没有成功。

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

我还尝试将语句的 SELECT 部分中的 Opportunity_Name 引用更改为:ISNULL(Opportunity_Name, 'x') – 这没有要么工作。

任何人都可以建议一种方法来使列表包含所有记录,而不管它们在机会名称中是否具有 Null 值?非常感谢!!!

我认为这是因为默认的 JOIN 语句丢弃了两个表中不匹配的行。您可以使用 LEFT JOIN 解决此问题。

示例:

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

可以看到第一个查询returns只有一条记录,而第二个returns两个。

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;

您需要确保在 table 机会中使用 LEFT JOIN。这将保留与商机 table.

中的记录无关的记录

此外,请注意不要使用 WHERE 子句过滤记录,因为商机 table 被 LEFT JOINED。在 LEFT JOIN ... ON 子句中包括那些与机会相关的过滤条件。