Mysql 如何在具有组合键列表的表上执行SELECT?

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,我想知道

如果我有一个列如下的表

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,我想知道如何在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