我有一组表,如下所示
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)
那里有很多连接,所以如果有人能够了解一下这个子查询的性能如何,那就太棒了! :)
答案 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)
)