Sql COALESCE整行?

时间:2011-09-13 20:47:53

标签: sql

我刚刚了解了COALESCE,我想知道是否可以在两个表之间COALESCE整行数据?如果没有,对于以下随机播放的最佳方法是什么?

例如,我有这两个表并假设所有列都匹配:

tbl_Employees

Id     Name     Email     Etc
-----------------------------------
1      Sue      ...       ...  
2      Rick     ...       ...  

tbl_Customers

Id     Name     Email     Etc
-----------------------------------
1      Bob      ...       ...  
2      Dan      ...       ...  
3      Mary     ...       ... 

一张id为的表:

tbl_PeopleInCompany

Id     CompanyId 
-----------------
1      1
2      1
3      1

我想以一种方式查询数据,从第一个表中获取匹配id的行,但如果没有找到id,则从第二个表获取。

因此生成的查询看起来像:

Id     Name     Email     Etc
-----------------------------------
1      Sue      ...       ...  
2      Rick     ...       ...  
3      Mary     ...       ... 

Sue和Rick从第一张桌子中取出,Mary从第二张桌子中取出。

4 个答案:

答案 0 :(得分:7)

 SELECT Id, Name, Email, Etc FROM tbl_Employees
      WHERE Id IN (SELECT ID From tbl_PeopleInID)
 UNION ALL
 SELECT Id, Name, Email, Etc FROM tbl_Customers
      WHERE Id IN (SELECT ID From tbl_PeopleInID) AND
            Id NOT IN (SELECT Id FROM tbl_Employees)

根据行数的不同,有几种不同的方法可以编写这些查询(使用JOIN和EXISTS),但首先尝试一下。

此查询首先从目标列表中具有Id值的tbl_Employees中选择所有人(表tbl_PeopleInID)。然后添加到第一个查询结果的这一行的“底部”。第二个查询获取目标列表中包含ID的所有tbl_Customer行,但不包括任何包含在tbl_Employees中出现的ID的行。

总列表包含您想要的人 - 来自tbl_PeopleInID的所有ID,优先考虑员工,但缺少从客户处提取的记录。

答案 1 :(得分:3)

你也可以这样做:

1)外部加入tbl_Employees.Id = tbl_Customers.Id上的两个表。这将为您提供tbl_Employees中的所有行,如果没有匹配的行,则将tbl_Customers列保留为null。

2)根据tbl_Customers.Id是否为NULL,使用CASE WHEN选择tbl_Employees列或tbl_Customers列,如下所示:

CASE WHEN tbl_Customers.Id IS NULL THEN tbl_Employees.Name ELSE tbl_Customers.Name END AS Name

(我的语法在那里可能不完美,但技术很合理。)

答案 2 :(得分:0)

我认为COALESCE功能不能用于您的想法。 COALESCE类似于ISNULL,除了它允许您传入多个列,并将返回第一个非空值:

SELECT Name, Class, Color, ProductNumber,
COALESCE(Class, Color, ProductNumber) AS FirstNotNull
FROM Production.Product

本文应该解释它的应用:

http://msdn.microsoft.com/en-us/library/ms190349.aspx

听起来Larry Lustig的回答更像是你所需要的。

答案 3 :(得分:0)

这应该是非常高效的。它使用CTE基本上构建了一个没有匹配的Employee记录的Customer小表,然后它只是UNION s带有Employee记录的结果

;WITH FilteredCustomers (Id, Name, Email, Etc)
AS
(
    SELECT  Id, Name, Email, Etc
    FROM    tbl_Customers C
            INNER JOIN tbl_PeopleInCompany PIC
            ON C.Id = PIC.Id
            LEFT JOIN tbl_Employees E
            ON C.Id = E.Id
    WHERE   E.Id IS NULL
)

SELECT  Id, Name, Email, Etc
FROM    tbl_Employees E
        INNER JOIN tbl_PeopleInCompany PIC
        ON C.Id = PIC.Id

UNION

SELECT  Id, Name, Email, Etc
FROM    FilteredCustomers

使用IN运算符可能会对大型查询造成负担,因为它可能必须为每个正在处理的记录计算子查询。