为具有2个分支的表编写SQL语句

时间:2011-07-27 06:32:35

标签: mysql sql

我有一组表,如下所示

A ---- B_has_A ---- B ---- C ---- D_has_C ---- D
                           |
                           | ---- E_has_C ---- E

我正在尝试编写一个允许我一起加入A,B,D的查询,然后从整个数据集中选择包含在D和E中的查询。

我编写了一个查询,可以从“E”分支找到所有内容:

SELECT DISTINCT B.module, B.controller, B.action, B.object_only, B.description, privileges.object_id, A.A_id
  FROM C JOIN(
    B
    LEFT JOIN (
      B_has_A JOIN A
      ON A.A_id = B_has_A.A_id)
    ON (B.B_id = B_has_A.B_id))
  ON (C.B_id = B.B_id)
JOIN (E JOIN E_has_C)
  ON (E.E_id = E_has_C.E_id AND C.C_id = E_has_C.C_id)
  WHERE E.E_id IN (2,3)

我也可以写一个我可以从“D”分支找到的东西:

SELECT DISTINCT B.module, B.controller, B.action, B.object_only, B.description, privileges.object_id, A.A_id
  FROM C JOIN(
    B
    LEFT JOIN (
      B_has_A JOIN A
      ON A.A_id = B_has_A.A_id)
    ON (B.B_id = B_has_A.B_id))
  ON (C.B_id = B.B_id)
JOIN (D JOIN D_has_C)
  ON (D.D_id = D_has_C.D_id AND C.C_id = D_has_C.C_id)
  WHERE D.D_id IN (1, 2)

如何编写一个可以从“D”和“E”分支获取所有内容的查询?我尝试使用连接,但它不起作用,MySQL说有语法错误:

SELECT DISTINCT B.module, B.controller, B.action, B.object_only, B.description, privileges.object_id, A.A_id
  FROM C JOIN(
    B
    LEFT JOIN (
      B_has_A JOIN A
      ON A.A_id = B_has_A.A_id)
    ON (B.B_id = B_has_A.B_id))
  ON (C.B_id = B.B_id)

JOIN (D JOIN D_has_C)
  ON (D.D_id = D_has_C.D_id AND C.C_id = D_has_C.C_id)
  WHERE D.D_id IN (1, 2)

JOIN (E JOIN E_has_C)
  ON (E.E_id = E_has_C.E_id AND C.C_id = E_has_C.C_id)
  WHERE E.E_id IN (2,3)

任何指示赞赏:)

编辑:最终解决方案。

谢谢大家。很多好主意。我的最终解决方案类似于ypercube的“不使用括号的连接:

SELECT ... long list
   FROM
     C    
   JOIN      
     B        
      ON C.B_id = B.B_id

   LEFT JOIN
     B_has_A
      ON B.B_id = B_has_A.B_id

   LEFT JOIN
     A
       ON A.A_id = B_has_A.A_id

   LEFT JOIN
      D_has_C
         ON C.C_id = D_has_C.C_id

   LEFT JOIN
      D
         ON D.D_id = D_has_C.D_id

   LEFT JOIN 
      E_has_C
         ON E.E_id = E_has_C.E_id

   LEFT JOIN
      E
         ON AND C.C_id = E_has_C.C_id

    WHERE E.E_id IN (2,3) OR D.D_id IN (1,2)

那里有很多连接,所以如果有人能够了解一下这个子查询的性能如何,那就太棒了! :)

3 个答案:

答案 0 :(得分:0)

您可以将两个查询的结果与UNION结合起来。连接只能用于组合表的某些行,而不是整个结果集。

SELECT DISTINCT B.module, B.controller, B.action, B.object_only, B.description, privileges.object_id, A.A_id
  FROM C JOIN(
    B
    LEFT JOIN (
      B_has_A JOIN A
      ON A.A_id = B_has_A.A_id)
    ON (B.B_id = B_has_A.B_id))
  ON (C.B_id = B.B_id)
JOIN (E JOIN E_has_C)
  ON (E.E_id = E_has_C.E_id AND C.C_id = E_has_C.C_id)
  WHERE E.E_id IN (2,3)

UNION ALL

SELECT DISTINCT B.module, B.controller, B.action, B.object_only, B.description, privileges.object_id, A.A_id
  FROM C JOIN(
    B
    LEFT JOIN (
      B_has_A JOIN A
      ON A.A_id = B_has_A.A_id)
    ON (B.B_id = B_has_A.B_id))
  ON (C.B_id = B.B_id)
JOIN (D JOIN D_has_C)
  ON (D.D_id = D_has_C.D_id AND C.C_id = D_has_C.C_id)
  WHERE D.D_id IN (1, 2)

答案 1 :(得分:0)

你试过而不是:

JOIN (D JOIN D_has_C)
  ON (D.D_id = D_has_C.D_id AND C.C_id = D_has_C.C_id)
  WHERE D.D_id IN (1, 2)

JOIN (E JOIN E_has_C)
  ON (E.E_id = E_has_C.E_id AND C.C_id = E_has_C.C_id)
  WHERE E.E_id IN (2,3)

这样:

JOIN (D JOIN D_has_C)
  ON ((D.D_id = D_has_C.D_id AND C.C_id = D_has_C.C_id) AND D.D_id IN (1, 2))

JOIN (E JOIN E_has_C)
  ON ((E.E_id = E_has_C.E_id AND C.C_id = E_has_C.C_id) AND  E.E_id IN (2,3))

答案 2 :(得分:0)

您也可以尝试删除括号:

  SELECT ... long list 
  FROM
      C
    JOIN
      B
        ON C.B_id = B.B_id
    LEFT JOIN 
      B_has_A
        ON B.B_id = B_has_A.B_id
    JOIN 
      A
        ON A.A_id = B_has_A.A_id
    JOIN 
      D_has_C
        ON C.C_id = D_has_C.C_id
    JOIN
      D
        ON D.D_id = D_has_C.D_id
    JOIN
      E_has_C
        ON E.E_id = E_has_C.E_id
    JOIN
      E 
        ON AND C.C_id = E_has_C.C_id 
  WHERE E.E_id IN (2,3)
    AND D.D_id IN (1,2)

这取决于您的表格之间的1对多关系,但您可能需要GROUP BY C.C_id,然后您可以移除DISTINCT


<强>更新

“来自D或E表”提示EXISTS

  SELECT B.module, B.controller, B.action
       , B.object_only, B.description, A.A_id 
  FROM
      C
    JOIN
      B
        ON C.B_id = B.B_id
    LEFT JOIN 
      B_has_A
        ON B.B_id = B_has_A.B_id
    JOIN 
      A
        ON A.A_id = B_has_A.A_id
WHERE EXISTS
  ( SELECT *
    FROM     
      D
    JOIN 
      D_has_C
        ON D.D_id = D_has_C.D_id
    WHERE C.C_id = D_has_C.C_id
      AND D.D_id IN (1,2)
  ) 
  OR EXISTS                        <--- Note the "OR"  
  ( SELECT *
    FROM
      E 
    JOIN
      E_has_C
        ON E.E_id = E_has_C.E_id
    WHERE C.C_id = E_has_C.C_id
      AND E.E_id IN (2,3)
  )
相关问题