代码之家  ›  专栏  ›  技术社区  ›  Mawg says reinstate Monica

MySql自连接查询

  •  3
  • Mawg says reinstate Monica  · 技术社区  · 6 年前

    mysql> describe skill_usage;
    +----------+---------+------+-----+---------+-------+
    | Field    | Type    | Null | Key | Default | Extra |
    +----------+---------+------+-----+---------+-------+
    | skill_id | int(11) | NO   | MUL | NULL    |       |
    | job_id   | int(11) | NO   | MUL | NULL    |       |
    +----------+---------+------+-----+---------+-------+
    

    在我的数据中,有一个 job_id skill_id 3和4:

    mysql>  select * from skill_usage;
    +----------+--------+
    | skill_id | job_id |
    +----------+--------+
    |        1 |      1 |
    |        2 |      2 |
    |        3 |      3 |     <----  matches only one part of the AND clause
    |        3 |      4 |     <----  matches only one part of the AND clause
    |        2 |      5 |
    |        3 |      6 |     <==== matches both parts of the AND clause
    |        4 |      6 |     <====
    |        2 |      7 |
    +----------+--------+
    8 rows in set (0.00 sec)
    

    我试了一下:

    SELECT DISTINCT s1.job_id FROM skill_usage AS s1 
      INNER JOIN skill_usage AS s2 ON s1.job_id = s2.job_id
        WHERE s1.skill_id IN (3,4)
        AND   s2.skill_id IN (3,4)
    

    我以为这意味着“找到一切” 作业编号 技能?id 技能?id 4英寸。

    显然不是:

    mysql> SELECT DISTINCT s1.job_id FROM skill_usage AS s1
        ->   INNER JOIN skill_usage AS s2 ON s1.job_id = s2.job_id
        ->     WHERE s1.skill_id IN (3,4)
        ->     AND   s2.skill_id IN (3,4);
    +--------+
    | job_id |
    +--------+
    |      3 |
    |      4 |
    |      6 |
    +--------+
    3 rows in set (0.00 sec)
    

    我做错什么了?我的查询应该怎么读?我想是时候读一本好书或读一门课了,但没有一本是我自己封面的。

    我的查询正确 作业编号 =6,但错误(IMO),发现 AND 条款。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Abra BlueJK    6 年前

    替代方案。
    db fiddle )

    select s1.job_id
      from skill_usage s1
      where s1.skill_id = 3
        and s1.job_id in (
                           select s2.job_id
                             from skill_usage s2
                            where s2.skill_id = 4
                         )
    
        2
  •  3
  •   Tim Biegeleisen    6 年前

    您可以在此处使用聚合:

    SELECT job_id
    FROM skill_usage
    WHERE skill_id IN (3, 4)
    GROUP BY job_id
    HAVING MIN(skill_id) <> MAX(skill_id);
    

    CREATE INDEX idx ON skill_usage (skill_id, job_id);
    

    两个 WHERE HAVING 条款,如所写,是 ,并且应该能够利用此索引。