【问题标题】:Only use data from TableA when TableB has no matching entry仅在 TableB 没有匹配条目时使用来自 TableA 的数据
【发布时间】:2018-04-09 07:46:45
【问题描述】:

所以我有:

带有(不仅是名称 - 多列)的表 A:

| IDA        | Name        |
|:-----------|------------:|
| 1          |        John |
| 2          |       Jonas | 
| 3          |        Carl | 
| 4          |         Foo |
| 5          |         Bar |
| 6          |         Dog |

表 B(不仅是名称 - 多列):

| IDB        | Name        |
|:-----------|------------:|
| 1          |         Bob |
| 2          |        Lisa | 

主表:

| ID         | FKtoB       | FKtoA       |
|:-----------|------------:|------------:|
| 1          |           1 |           4 |
| 2          |             |           3 | 
| 3          |             |           1 | 
| 4          |           2 |           6 |
| 5          |             |           2 |
| 6          |             |           5 |

我的目标是从 MAIN 中选择并更喜欢使用表 B 的数据,但如果不可用,我将使用表 A 的数据。我尝试使用 coalesce 但这没有帮助,因为我不想混合数据,所以如果例如表 B 有一行的数据,那么在这一行中应该没有表 A 的数据。

我的查询看起来像这样:

select 
coalesce(b.name, a.name) as surname, coalesce(b.surname, a.surname) as surname 
from MAIN m
left join TableA a on a.IDA = m.FKtoA
left join TableB b on b.IDA = m.FKtoB

我的问题是,例如,如果 b.name 被填充,而 b.surname 不是,它会将 b.name 与 a.surname 混合,这在我的情况下是不行的。

【问题讨论】:

  • 那么你期望的输出是什么?即使它不起作用,发布您尝试过的内容也对您有好处;你能把edit也写进你的帖子吗?谢谢。
  • 你试过LEFT JOIN吗?
  • @Larnu 我添加了我的查询并解释了更多

标签: sql sql-server join coalesce


【解决方案1】:

也许您可以添加不存在的 b 作为连接条件:

select 
coalesce(b.name, a.name) as name, coalesce(b.surname, a.surname) as surname 
from MAIN m
left join TableB b on b.IDA = m.FKtoB
left join TableA a on a.IDA = m.FKtoA and b.IDA is null

编辑:将一个姓氏更正为姓名

【讨论】:

    【解决方案2】:

    试试Left JoinCase -

    SELECT
        M.ID, (CASE WHEN B.IDB IS NOT NULL THEN B.Name ELSE A.Name END) AS NAME
    FROM
        MAIN AS M
        LEFT JOIN TableB as B ON B.IDB = M.FKtoB
        LEFT JOIN TableA as A ON A.IDA = M.FKtoA
    

    【讨论】:

    • 这是一个很好的答案,我会尝试使用它,如果有效,我会给出回应
    【解决方案3】:

    从 SQL Server 2012(及更高版本)开始,您可以使用IIF

    SELECT
    IIF(m.FKtoB IS NULL, A.name, B.name) AS surname
    FROM MAIN m
    LEFT JOIN TableA a ON a.IDA = m.FKtoA
    LEFT JOIN TableB b ON b.IDA = m.FKtoB
    

    【讨论】:

      【解决方案4】:

      试试这个:

          declare @tableA table(IDA INT,Name varchar(MAX))
          declare @tableB table(IDB INT, Name VARCHAR(MAX))
          declare @tableMain table(ID INT,FKtoB INT,FKtoA INT)
      
          INSERT INTO @tableA
          SELECT 1,'John'
          union all
          SELECT 2, 'Jonas'
          union all
          SELECT 3, 'Carl'
          union all
          SELECT 4,'Foo'
          union all
          SELECT 5 ,'Bar'
          union all
          SELECT 6,'Dog'
      
      
          INSERT INTO @tableB
          SELECT 1, 'Bob'
          Union all
          SELECT 2, 'Lisa'
      
      
          INSERT INTO @tableMain
          SELECT 1,1,4
          union all
          SELECT 2,null,3
          union all
          SELECT 3,null,1
          union all
          SELECT 4,2,6
          union all
          SELECT 5,null,2
          union all
          SELECT 6,null,5
      
      
          Select tm.Id,ISNULL(tb.Name,ta.Name) As NAME from @tableMain tm
          LEFT JOIN @tableB tb on tm.FktoB=tb.IDb and IDb is not NUll
          LEFT JOIN @tableA tA on tm.FktoA=ta.IDA and FktoB is NUll
      

      【讨论】:

        【解决方案5】:

        只有当表 B 中没有匹配项时,您才想从表 A 中进行选择,因此给定的外键是完整的:

        select 
          coalesce(b.firstname, a.firstname) as firstname,
          coalesce(b.surname, a.surname) as surname,
          coalesce(b.birthday, a.birthday) as birthday,
          ...
        from MAIN m
        left join TableB b on b.IDB = m.FKtoB
        left join TableA a on a.IDA = m.FKtoA and m.FKtoB is null;
        

        另一种方法是联合所有:

        select firstname, surname, birthday, ...
        from TableB 
        where IDB in (select FKtoB from MAIN)
        union all
        select firstname, surname, birthday, ...
        from TableA 
        where IDA in (select FKtoA from MAIN where FKtoB is null);
        

        【讨论】:

        • 谢谢,效果也不错,我更喜欢第一种解决方案
        【解决方案6】:

        试试这个。它会给出你想要的结果。

        (select ida as ID ,
        case when ida is not null then ida end fkToIda,
         case when idb is not null then idb end fkToIdB 
         from A
        left outer join B on a.ida=b.idb)
        
        union
        
        (select idb ,
        case when ida is not null then ida end,
         case when idb is not null then idb end 
         from A
        right outer join B on a.ida=b.idb)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-14
          • 1970-01-01
          • 2020-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多