如果这个问题以前出现过,我很抱歉,但我找不到一个可靠的答案。
我正试图从我的表中与另一个表连接的一组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中处理它。如果我可以将表用于以下多个查询,那么这将是双重理想的,因为在连接的表中有可以稍后使用的额外数据。
抱歉,如果这是天真的,但我不是一个真正的大型web开发人员。提前谢谢。
编辑:我正在寻找临时表,似乎这可能是一个很好的方法。在做任何事情之前,我还是想确认一下这是不是一个好主意。
没有捷径——除非改变表的设计。你的方法是可靠的,你不应该担心在你的查询中有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 ...
Try 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