【问题标题】:t-sql query to get all the rows from Table_A which have at least one matching relatedid in Table_Bt-sql 查询从 Table_A 中获取在 Table_B 中至少有一个匹配的相关 ID 的所有行
【发布时间】:2011-04-05 01:04:58
【问题描述】:

根据下表

Table_A

Id  RelatedId
---------------
1   1
1   2
1   3
2   4
2   5
2   2
3   7
3   8
4   9

Table_B

RelatedId  Name
--------------
2          A
3          B

我想从 Table_A 中获取在 Table_B 中至少有一个匹配的相关 ID 的所有行。 Table_A 中与 Table_B 不匹配的 Id 在结果表中将只有一行。

所以这种情况下的输出(结果表)将是

Id  RelatedId
---------------
1   1
1   2
1   3
2   4
2   5
2   2
3   Null
4   Null

编辑:似乎问题文本让许多人感到困惑。所以详细解释一下:

Table_A Id 1 在 table_B 中有 2 和 3(相关 Id)匹配。因此输出将包含 Table_A 中 1 的所有行。 Table_A 中的相似 ID 2 在 table_B 中有 2 个(相关 ID)匹配。因此,Table_A 中对应于 2 的所有行都将被拾取。由于 3 在 table_B 中没有任何匹配的相关 ID,因此将显示但在结果表中以 NULL 作为相关 ID。

【问题讨论】:

    标签: sql tsql sql-server-2008


    【解决方案1】:

    试试:

      Select Distinct Id, Related_Id
      From Table_A 
      Where Related_Id In 
          (Select Related_Id From Table_B) 
    

    【讨论】:

    • 以上没有给出想要的结果。我想我的解释不清楚。如果特定 Id 在 Table_B 中至少有一个匹配的 RelatedId,则输出必须包含来自 Table_A 的所有行。因此,在这种情况下,来自 Table_A 的 Id 1 在 table_B 中同时具有 2 和 3 匹配。因此输出将包含 Table_A 中 1 的所有行。 Table_A 中的相似 ID 2 在 table_B 中有 2 个匹配项。因此,Table_A 中对应于 2 的所有行都将被拾取。由于 3 在 table_B 中没有任何匹配的相关 ID,它将被显示,但在结果表中以 NULL 作为相关 ID。
    • 啊,不清楚...我将进行编辑以更正...正如您刚刚阐明的那样,您想要的只是 Table_A 中相关 ID 在 Table_B 中的行?然后修改后的 sql 应该可以解决问题
    • 实际上它没有给出预期的结果。你能请。让我知道上面查询中对应的别名“B”是什么??
    • '这是我需要从编辑第一个 sql 时删除的错字,我未能删除...现在应该可以工作了..
    【解决方案2】:
    with validids as (
     select distinct id 
     from Table_A 
      inner join Table_B on 
       Table_A.relatedid = Table_B.relatedid
    )
    select 
      id,
      relatedid
    from Table_A 
    where id in (select id from validids)
    union 
    select distinct
     id, 
     null
    from Table_A
    where id not in (select id from validids)
    

    【讨论】:

    • 这不仅仅是一个外连接问题。结果包含比标准外部联接显示的信息更多的信息。
    • 是的,这是我取消删除的原始答案,因此我可以输入真正的答案。不幸的是,当我编辑它时,你们都可以再次看到答案。
    • 任何收回-1的机会
    • 恢复得很好。我喜欢新的答案。抱歉,我扣动了 -1 扳机。我会在我力所能及的地方还给它。你去,2点开关。 :)
    • @Chris:谢谢。这给出了所需的输出。 +1 和绿色检查 :)
    【解决方案3】:

    这应该做你想做的:

    with IdsWithMatchInB(Id) as (
      select distinct
        Id
      from Table_A
      where Table_A.RelatedId in (
        select Table_B.RelatedId
        from Table_B
      )
    )
      select
        Table_A.Id,
        CASE WHEN IdsWithMatchInB.Id IS NULL
             THEN NULL
        ELSE Table_A.RelatedId END AS RelatedId
    from Table_A
    left outer join IdsWithMatchInB
    on IdsWithMatchInB.Id = Table_A.Id
    

    这是另一个通过将子查询放在 CASE 表达式中来避免 DISTINCT 的选项:

    select
      Id,
      case when Id in (
        select Id
        from Table_A as Acopy
        where Acopy.RelatedId in (
          select
            RelatedId 
          from Table_B
        )
      )
      then RelatedId
      else null end as RelatedId
    from Table_A;
    

    其中一个可能对您的特定数据和索引更有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-22
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多