从两个表中选择结果,但选择一个字段而不是另一个

时间:2016-05-20 14:07:36

标签: sql sql-server sql-server-2012

我有两张桌子。

tblEmployee                  tblExtraOrMissingInfo

id nvarchar(10)              id nvarchar(10)
Name nvarchar(50)            Name nvarchar(50)
                             PreferredName nvarchar(50)
                             UsePreferredName bit

数据(简要示例)

 tblEmployee                 tblExtraOrMissingInfo
 id     Name                 id     Name         PreferredName   UsePreferredName 
 AB12   John                 PN01   Peter        Tom             1
 LM22   Lisa                 YH76   Andrew       Andy            0
 PN01   Peter                LM22   Lisa         Liz             0
 LK655  Sarah

我想要一个查询来产生以下结果

 id     Name
 AB12   John
 LM22   Lisa
 PN01   Tom 
 YH76   Andrew
 LK655  Sarah

所以我想要的是tblEmployee返回的所有记录以及tblExtraOrMissingInfo中尚未包含在tblEmployee中的任何记录。

如果两个表中都有一个具有相同id的记录,我希望如果tblExtraOrMissingInfo中的UsePreferredName字段对于要使用的PreferredName而不是tblEmployee中的Name字段为1,请参阅示例中的记录PN01上方。

5 个答案:

答案 0 :(得分:4)

使用左连接和合并比使用case语句稍快一些(大多数服务器都针对合并进行了优化)。

像这样:

 SELECT E.ID, COALESCE(P.PreferredName,E.Name,'Unknown') as Name
 FROM tblemployee E
 LEFT JOIN tblExtraOrMissingInfo P ON E.ID = P.ID AND P.UsePreferredName = 1
  

我不需要,'Unknown'来回答您的问题,但我补充道   这里表明你可以增强这个查询来处理的情况   两个表中都没有名称,您不希望结果中出现空值

答案 1 :(得分:2)

在employee表上

left join并使用case表达式作为名称。

select e.id
,case when i.UsePreferredName = 1 then i.PreferredName else e.name end as name
from tblemployee e
left join tblExtraOrMissingInfo i on i.id=e.id

答案 2 :(得分:0)

您可以LEFT OUTER JOIN将这些表放在一起,然后使用CASE语句和COALESCE()公式来获取此信息:

SELECT
    tblEmployee.id,
    CASE WHEN UsePreferredName = 1 THEN COALESCE(PreferredName, tblEmployee.Name) ELSE tblEmployee.name
FROM 
    tblEmployee
    LEFT OUTER JOIN tblExtraOrMissingInfo 
        ON tblEmployee.id = tblExtraOrMissingInfo.id

CASE检查usePreferredName值,COALESCE()然后抓取PreferredName,除非它为NULL。然后它从tblEmployee获取员工姓名。

答案 3 :(得分:-1)

select id ,name 
from
(
select  id ,name from tblEmployee 
union all
select id ,name from tblExtraOrMissingInfo
)group by id,name

答案 4 :(得分:-1)

这是您可以实现结果的另一种方式。您也可以使用CTE获得相同的结果。

CREATE TABLE #tblEmployee
    (
      id NVARCHAR(10)
    , Name NVARCHAR(50)
    );

CREATE TABLE #tblExtraOrMissingInfo
    (
      id NVARCHAR(10)
    , Name NVARCHAR(50)
    , PreferredName NVARCHAR(50)
    , UsePreferredName BIT
    );

INSERT  INTO #tblEmployee
        ( id, Name )
VALUES  ( N'AB12'  -- id - nvarchar(10)
          , N'John'  -- Name - nvarchar(50)
          ),
        ( N'LM22'  -- id - nvarchar(10)
          , N'Lisa'  -- Name - nvarchar(50)
          ),
        ( N'PN01'  -- id - nvarchar(10)
          , N'Peter'  -- Name - nvarchar(50)
          ),
        ( N'LK655'  -- id - nvarchar(10)
          , N'Sarah'  -- Name - nvarchar(50)
          );

INSERT  INTO #tblExtraOrMissingInfo
        ( id, Name, PreferredName, UsePreferredName )
VALUES  ( N'PN01'  -- id - nvarchar(10)
          , N'Peter'  -- Name - nvarchar(50)
          , N'Tom'  -- PreferredName - nvarchar(50)
          , 1  -- UsePreferredName - bit
          ),
        ( N'YH76'  -- id - nvarchar(10)
          , N'Andrew'  -- Name - nvarchar(50)
          , N'Andy'  -- PreferredName - nvarchar(50)
          , 0  -- UsePreferredName - bit
          ),
        ( N'LM22'  -- id - nvarchar(10)
          , N'Lisa'  -- Name - nvarchar(50)
          , N'Liz'  -- PreferredName - nvarchar(50)
          , 0  -- UsePreferredName - bit
          );

SELECT  R.id
      , CASE WHEN tbl.UsePreferredName = 1 THEN tbl.PreferredName
             ELSE R.Name
        END AS NAME
FROM    #tblExtraOrMissingInfo tbl
        RIGHT JOIN ( SELECT id
                          , Name
                     FROM   #tblEmployee
                     UNION
                     SELECT id
                          , Name
                     FROM   #tblExtraOrMissingInfo
                   ) AS R
        ON R.id = tbl.id
           AND R.Name = tbl.Name;