Mysql 如何在具有组合键列表的表上执行SELECT?
如果我有一个列如下的表 ID1 ID2 VAL1 VAL2 其中ID1、ID2构成主键索引 如何为特定的ID1、ID2值执行任何SQL语句 示例:我有一个包含PK(1,1)(1,2)(2,4)(2,1)(3,1)(3,2)(3,5)的记录的表 我只想选择具有(1,1)(1,2)(3,5)(3,2)的记录 使用 从tbl1中选择*,其中ID1在(1,3)中,ID2在(1,2,5)中 将产生不期望的结果:(3,1)。那么最好的方法是什么呢Mysql 如何在具有组合键列表的表上执行SELECT?,mysql,sql,postgresql,Mysql,Sql,Postgresql,如果我有一个列如下的表 ID1 ID2 VAL1 VAL2 其中ID1、ID2构成主键索引 如何为特定的ID1、ID2值执行任何SQL语句 示例:我有一个包含PK(1,1)(1,2)(2,4)(2,1)(3,1)(3,2)(3,5)的记录的表 我只想选择具有(1,1)(1,2)(3,5)(3,2)的记录 使用 从tbl1中选择*,其中ID1在(1,3)中,ID2在(1,2,5)中 将产生不期望的结果:(3,1)。那么最好的方法是什么呢 我正在寻找SQL的总体答案,但如果它依赖于DBMS,我想知道
我正在寻找SQL的总体答案,但如果它依赖于DBMS,我想知道如何在PostgreSQL和MySQL中实现这一点。您可以使用
和和或实现这一点:
SELECT *
FROM tbl1
WHERE ID1 = 1 AND ID2 = 1 OR
ID1 = 1 AND ID2 = 2 OR
ID1 = 3 AND ID2 = 5 OR
ID1 = 2 AND ID2 = 2
MySQL和PostgreSQL都支持中的元组,如下所示
SELECT *
FROM tbl1
WHERE (ID1,ID2) IN ((1,1) (1,2) (2,4) (2,1) (3,1) (3,2) (3,5));
这可能是实现您要求的最简洁的方式:
SELECT *
FROM tbl1
WHERE (ID1 = 1 AND (ID2 = 1 OR ID2 = 2))
OR (ID1 = 3 AND (ID2 = 5 OR ID2 = 2));
或
你也可以试试
SELECT
*
FROM
tbl1
JOIN
(
SELECT 1 AS ID1, 1 AS ID2
UNION ALL
SELECT 1 AS ID1, 2 AS ID2
UNION ALL
SELECT 2 AS ID1, 4 AS ID2
UNION ALL
SELECT 2 AS ID1, 1 AS ID2
UNION ALL
SELECT 3 AS ID1, 1 AS ID2
UNION ALL
SELECT 3 AS ID1, 2 AS ID2
UNION ALL
SELECT 3 AS ID1, 5 AS ID2
) as keylist ON tbl1.ID1 = keylist.ID1 AND tbl1.ID2 = keylist.ID2
想必这是唯一的办法?它还会使用主键索引吗?在处理复合键时,SQL突然似乎有一个低效的语言障碍。这就是我要寻找的。PostgreSQL也支持这种语法。然而,我想知道它是否遵循最左边的前缀规则来使用主键索引。@RonaldChan-你必须看看解释计划。无法想象该结构会给相应的优化人员带来任何特殊问题,但不确定。谢谢。至少在Postgres中是这样。@RonaldChan:主键在(ID1,ID)
上创建一个多列。只要这两列都包含在条件中,索引将被同等有效地使用。我写了更多,还有链接。@ErwinBrandstetter-链接中的回答很好。我错过了第一轮!如果有人想使用这个可怕的构造,一定要做到。此外,除了第一个union外,不需要在任何情况下提供列别名-选择
@ErwinBrandstetter感谢union ALL heads up,我忘记了在这种情况下可以忽略不计的性能优势,因为结果集太小了。我保留字段名的原因是为了可读性。这是因为我相信,准则的目标应该在实际准则中明确。当性能是需要改进的时候,程序员应该只关注性能。。
SELECT * FROM tbl1 WHERE (ID1 = 1 AND ID2 IN (1,2)) OR (ID1 = 3 AND ID2 IN (5,2))
SELECT
*
FROM
tbl1
JOIN
(
SELECT 1 AS ID1, 1 AS ID2
UNION ALL
SELECT 1 AS ID1, 2 AS ID2
UNION ALL
SELECT 2 AS ID1, 4 AS ID2
UNION ALL
SELECT 2 AS ID1, 1 AS ID2
UNION ALL
SELECT 3 AS ID1, 1 AS ID2
UNION ALL
SELECT 3 AS ID1, 2 AS ID2
UNION ALL
SELECT 3 AS ID1, 5 AS ID2
) as keylist ON tbl1.ID1 = keylist.ID1 AND tbl1.ID2 = keylist.ID2