我不是SQL专家,但很少提出一个返回所需结果的查询(即使它是次优的)。但是这个让我陷入困境。
我有两张桌子,人和组织。人们有一个FK到组织(一个人可以有一个组织,但默认为NULL)。我正在尝试运行一个搜索查询,该搜索查询将提取人员(包含来自“组织”表的几个字段),如下所示:
DECLARE
@text nvarchar(100) = 'test',
@jobTitle nvarchar(100) = NULL,
@orgName nvarchar(100) = NULL,
@industry nvarchar(100) = NULL,
@location nvarchar(100) = NULL,
@status nvarchar(100) = NULL
SELECT
PeopleId AS 'ID',
FirstName + ' ' + People.LastName AS 'People',
Email AS 'Email',
JobTitle AS 'Job Title',
Location AS 'Location',
Organizations.Name AS 'Employer',
Organizations.Industry AS 'Industry',
People.Status AS 'Status'
FROM
People, Organizations
WHERE
(People.Organization = Organizations.OrganizationId)
AND ((FirstName LIKE '%' + @text + '%' OR
LastName LIKE '%' + @text + '%' OR
Email LIKE '%' + @text + '%' OR
@text IS NULL)
AND (JobTitle LIKE '%' + @jobTitle + '%'
OR @jobTitle IS NULL)
AND (Organizations.Name LIKE '%' + @orgName + '%'
OR @orgName IS NULL)
AND (Organizations.Industry LIKE '%' + @industry + '%'
OR @industry IS NULL)
AND (Location LIKE '%' + @location + '%'
OR @location IS NULL)
AND (People.Status LIKE '%' + @status + '%'
OR @location IS NULL)
);
这将返回合适的人员(但该表中的每个组织都有一行)。谁能告诉我我做错了什么?
我想我可能需要在OR People.Organization IS NULL
下的第一个条款中添加WHERE
条件,但这根本不会带来任何结果:(
非常感谢。
答案 0 :(得分:1)
您需要左外连接
FROM
People
LEFT OUTER JOIN
Organizations ON (People.Organization = Organizations.OrganizationId)
问题在于FROM People, Organizations
创建了一个所谓的"交叉产品"或者"笛卡儿产品"这两个表中包含所有人员与所有组织的所有组合。当条件(People.Organization = Organizations.OrganizationId)
仅从十字产品中获取有意义的组合时,它找不到没有组织的人。它没有机会找到它们,因为在交叉产品中只能找到与某些组织配对的人。
左外连接正是您所需要的。这需要所有的人(这是"左外"的意思),以及组织,只要它找到。如果它没有找到它,组织的所有字段似乎都为空,但People记录仍然存在。
答案 1 :(得分:1)
你的基本问题是你需要一个Stefan所涵盖的左连接,但是我想指出另一个可以用于null参数默认为“ALL”的技巧
而不是像这样的构造
AND (Organizations.Industry LIKE '%' + @industry + '%'
OR @industry IS NULL)
使用COALESCE功能
AND (Organizations.Industry LIKE '%' + COALESCE(@industry,Organizations.Industry) + '%'
我还要指出像这样的“通配符”搜索非常慢(不能使用索引。如果你知道你的输入是准确的(例如从下拉列表中),那就更好了:
AND Organizations.Industry = COALESCE(@industry,Organizations.Industry)