Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 从两个表中选择匹配的对_Mysql_Sql - Fatal编程技术网

Mysql 从两个表中选择匹配的对

Mysql 从两个表中选择匹配的对,mysql,sql,Mysql,Sql,我需要从包含相似结构数据的两个表中选择匹配对。这里的Matched Pair是指在“match”列中相互引用的两行 单表匹配对示例: TABLE ---- id | matchid 1 | 2 2 | 1 ID 1和ID 2是匹配的对,因为它们各自都有一个对应于另一个的匹配项 现在真正的问题是:选择两个表中出现的匹配对的最快方法是什么: Table ONE (id, matchid) Table TWO (id, matchid) 示例数据: ONE

我需要从包含相似结构数据的两个表中选择匹配对。这里的Matched Pair是指在“match”列中相互引用的两行

单表匹配对示例:

TABLE
----
id | matchid
1  |   2
2  |   1
ID 1和ID 2是匹配的对,因为它们各自都有一个对应于另一个的匹配项

现在真正的问题是:选择两个表中出现的匹配对的最快方法是什么:

Table ONE (id, matchid)
Table TWO (id, matchid)
示例数据:

ONE                TWO
----               ----
id  | matchid      id  | matchid
1   |   2          2   |   3
2   |   3          3   |   2
3   |   2
4   |   5
5   |   4
所需的结果是ID为2和3的单行

RESULT
----
id  | id
2   | 3
这是因为表1和表2中的2和3是匹配对。4和5是表1中的匹配对,但不是表2中的匹配对,因此我们不选择它们。1和2根本不是匹配对,因为2没有1的匹配项

我可以从一个表中获得匹配的配对:

SELECT a.id, b.id 
    FROM ONE a JOIN ONE b
       ON a.id = b.matchid AND a.matchid = b.id
    WHERE a.id < b.id
我应该如何构建一个只选择两个表中出现的匹配对的查询

我应该:

为每个表选择上面的查询以及它们一起存在的位置? 为每个表选择上面的查询并将它们连接在一起? 选择上面的查询,然后两次联接表,一次联接“id”,一次联接“matchid”? 为每个表选择上面的查询并循环,以便在php中对它们进行比较? 以某种方式过滤表2,这样我们只需查看表1中匹配对中的ID? 做些完全不同的事?
由于这是一个效率问题,值得注意的是,匹配将非常稀疏,可能是1/1000或更少,每个表将有100000多行。

我想我明白你的意思。您希望筛选两个表上存在对的记录


我想我明白你的意思了。您希望筛选两个表上存在对的记录

请尝试以下查询:

已编辑的查询:

请尝试以下查询:

已编辑的查询:


Naive版本,它检查需要存在的所有四行:

-- EXPLAIN ANALYZE
WITH both_one AS (
        SELECT o.id, o.matchid
        FROM one o
        WHERE o.id < o.matchid
        AND EXISTS ( SELECT * FROM one x WHERE x.id = o.matchid AND x.matchid = o.id)
        )
, both_two AS (
        SELECT t.id, t.matchid
        FROM two t
        WHERE t.id < t.matchid
        AND EXISTS ( SELECT * FROM two x WHERE x.id = t.matchid AND x.matchid = t.id)
        )
SELECT *
FROM both_one oo
WHERE EXISTS (
        SELECT *
        FROM both_two tt
        WHERE tt.id = oo.id AND tt.matchid = oo.matchid
        );
这个比较简单:

-- EXPLAIN ANALYZE
WITH pair AS (
        SELECT o.id, o.matchid
        FROM one o
        WHERE EXISTS ( SELECT * FROM two x WHERE x.id = o.id AND x.matchid = o.matchid)
        )
SELECT *
FROM pair pp
WHERE EXISTS (
        SELECT *
        FROM pair xx
        WHERE xx.id = pp.matchid AND xx.matchid = pp.id
        )
AND pp.id < pp.matchid
        ;

Naive版本,它检查需要存在的所有四行:

-- EXPLAIN ANALYZE
WITH both_one AS (
        SELECT o.id, o.matchid
        FROM one o
        WHERE o.id < o.matchid
        AND EXISTS ( SELECT * FROM one x WHERE x.id = o.matchid AND x.matchid = o.id)
        )
, both_two AS (
        SELECT t.id, t.matchid
        FROM two t
        WHERE t.id < t.matchid
        AND EXISTS ( SELECT * FROM two x WHERE x.id = t.matchid AND x.matchid = t.id)
        )
SELECT *
FROM both_one oo
WHERE EXISTS (
        SELECT *
        FROM both_two tt
        WHERE tt.id = oo.id AND tt.matchid = oo.matchid
        );
这个比较简单:

-- EXPLAIN ANALYZE
WITH pair AS (
        SELECT o.id, o.matchid
        FROM one o
        WHERE EXISTS ( SELECT * FROM two x WHERE x.id = o.id AND x.matchid = o.matchid)
        )
SELECT *
FROM pair pp
WHERE EXISTS (
        SELECT *
        FROM pair xx
        WHERE xx.id = pp.matchid AND xx.matchid = pp.id
        )
AND pp.id < pp.matchid
        ;

你不是想加入a.matchid=b.matchid吗?@sashkello-不完全是。表中必须有两行,每行相互匹配。那么这些匹配必须同时存在于两个表中。我不明白你的意思。这似乎是一个简单的问题,你把它复杂化了……请尝试下面我的答案:请注意,在多个表中存在id和matchid之间的关系等数据可能被认为是数据库设计不好的标志,因为它是多余的,因此容易出现不一致。你不是在尝试加入a.matchid=b.matchid吗?@sashkello-不完全是这样。表中必须有两行,每行相互匹配。那么这些匹配必须同时存在于两个表中。我不明白你的意思。这似乎是一个简单的问题,您把它复杂化了……请尝试下面我的答案:请注意,在多个表中存在id和matchid之间的关系这样的数据可能被认为是数据库设计不好的标志,因为它是冗余的,因此容易出现不一致。
-- EXPLAIN ANALYZE
WITH pair AS (
        SELECT o.id, o.matchid
        FROM one o
        WHERE EXISTS ( SELECT * FROM two x WHERE x.id = o.id AND x.matchid = o.matchid)
        )
SELECT *
FROM pair pp
WHERE EXISTS (
        SELECT *
        FROM pair xx
        WHERE xx.id = pp.matchid AND xx.matchid = pp.id
        )
AND pp.id < pp.matchid
        ;