T-SQL查询的正确语法

时间:2015-08-03 20:22:05

标签: sql-server tsql

我不是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条件,但这根本不会带来任何结果:(

非常感谢。

2 个答案:

答案 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)