所以我很抱歉,如果之前已经出现过,但我找不到可靠的答案。
我试图从我的表中的一组3列中获取一列id与另一个表连接。
用于获取单个列的select语句将如下所示:
SELECT id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue = X;
现在据我所知,我可以做工会来这样做:
SELECT spec_id1 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue1 = X
UNION
SELECT spec_id2 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue2 = Y
UNION
SELECT spec_id3 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue3 = Z
有没有办法重用TableA JOIN TableB USING(key1,key2)所以每次选择都没有连接?我还有一个WHERE条件,适用于上面未显示的所有选择。我可以重复使用像:
FROM TableA JOIN TableB USING (key1, key2) WHERE someOtherValue = W
我正在尝试使用mysqli在PHP中执行此操作。我原来的本能是使用临时表和查询,但我不知道如何在mysqli中处理它。如果我可以将该表用于多个后续查询,这将是双重理想的,因为在连接表中有额外的数据可以在以后使用。
对不起,如果这是天真的,但我不是一个真正的网络开发人员。提前谢谢。
编辑: 我正在研究临时表,看起来这可能是一个很好的方法。在做任何事情之前,我还是想确认这是否是个好主意。
答案 0 :(得分:1)
没有捷径 - 不是没有改变表格的设计。您的方法很可靠,您不必担心查询中有3个连接。
如果已知3个spec_id列表没有任何重叠值,则可以通过将UNION
更改为UNION ALL
来提高效果。
在不更改整体UNION
计划的情况下,一次可能的重写是将联接更改为EXISTS
子查询:
SELECT spec_id1 AS id
FROM TableA
WHERE EXISTS
( SELECT *
FROM TableB
WHERE (TableB.key1, TableB.key2) = (TableA.key1, TableA.key2)
AND someValue1 = X
)
UNION --- or UNION ALL
...
UNION
...
或 - 如果spec_ids
全部包含在另一个BaseTable
中 - 您可以拥有这样的内容,这可能会产生更好的执行计划:
SELECT id
FROM BaseTable
WHERE EXISTS
( SELECT * AS id
FROM TableA
JOIN TableB
USING (key1, key2)
WHERE someValue1
AND TableA.spec_id1 = BaseTable.id
)
OR EXISTS
(
...
)
OR ...
答案 1 :(得分:1)
尝试CASE声明。你应该能够在没有UNION
的情况下做到这一点SELECT
CASE
WHEN someValue1 = X THEN spec_id1
WHEN someValue2 = Y THEN spec_id2
WHEN someValue3 = Z THEN spec_id3
END
AS id FROM TableA JOIN TableB USING (key1, key2)
WHERE
someValue1 = X OR someValue2 = Y OR WHERE someValue3 = Z