【问题标题】:Table join with case表连接与案例
【发布时间】:2019-11-17 22:07:10
【问题描述】:

我们必须根据表 1 列 itemtype 连接 4 个表。

表A包含id,itemtype,itemid

表 B 包含 id、全名

表 c 包含 id、全名

表D包含id、全名

表 A.itemid 在(表 B 或表 C 或表 D)的 id 中。

我想将表 A 与剩余表连接起来以获得全名。根据 TableA 列 itemtype 值加入另一个表

     select
     tblA.itemid,y.fullname from tableA as tblA 
      inner join (
        CASE WHEN tblA.itemtype = 1 THEN 
          select
            tblB.itemid as id,tblB.fullname  as fullname
          from
            tableB    as tblB 
          where
            tblB.id = tblA.itemid
        WHEN tblA.itemtype = 2 THEN  
          select
            tblC.itemid as id,tblC.fullname  as fullname
          from
            tableC  as tblC  
          where
            tblC.id = tblA.itemid
            WHEN tblA.itemtype = 3 THEN 
              select
            tblD.itemid as id ,tblD.fullname as fullname
          from
            tableD  as tblD  
          where
            tblD.id = tblA.itemid

          END
      ) as bcd on bcd.id = tblA.itemid

【问题讨论】:

    标签: mysql


    【解决方案1】:

    您可以将left joinBCD 加入表A,并在ON 子句中包含itemtype 列的条件:

    select
      A.itemid,
      coalesce(B.fullname, C.fullname, D.fullname) fullname
    from A 
    left join B on B.id = A.itemid AND A.itemtype = 1
    left join C on C.id = A.itemid AND A.itemtype = 2
    left join D on D.id = A.itemid AND A.itemtype = 3
    

    请参阅demo
    或者使用 UNION ALL:

    select
      A.itemid,
      B.fullname
    from A inner join B on B.id = A.itemid 
    where A.itemtype = 1
    union all
    select
      A.itemid,
      C.fullname
    from A inner join C on C.id = A.itemid 
    where A.itemtype = 2
    union all
    select
      A.itemid,
      D.fullname
    from A inner join D on D.id = A.itemid 
    where A.itemtype = 3
    

    请参阅demo

    【讨论】:

    • 伟大的 Aksen,它运作良好。但问题是虽然 itemetype 不相关,但表是不必要的连接事件。例如:如果 itemtype =1 ,则不需要加入 TableC 和 Table D。所以它会影响性能。
    • 阿克森是谁?连接的原因是您不能在条件中连接 B 或 C 或 D(至少在没有动态 sql 的情况下不能)。您知道这一点是因为您尝试在查询中执行此操作。我的答案中的代码是你可以做的。此外,即使可以完成,每次检查条件并连接一个或另一个表的效率也会低得多。我的代码中的连接是必要的,因此由于条件 AND A.itemtype = ?,A 的每一行实际上只连接到一个表的行
    • 另一种实现相同目的的方法是使用 UNION ALL,但这会扫描表 3 次然后应用 UNION。
    【解决方案2】:

    如果关联表中的列不多:

    SELECT
       a.itemid,
       COALESCE(b.fullname, c.fullname, d.fullname, ' - Missing name - '))
    FROM
       tblA a 
       LEFT JOIN tblB b ON a.itemtype = 1 AND a.itemid = a.id
       LEFT JOIN tblC c ON a.itemtype = 2 AND a.itemid = b.id
       LEFT JOIN tblD d ON a.itemtype = 3 AND a.itemid = c.id
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 2020-03-31
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 2016-06-21
      • 1970-01-01
      相关资源
      最近更新 更多