42

我有两个表,记录和数据。记录有多个字段(名字、姓氏等)。这些字段中的每一个都是存储实际值的数据表的外键。我需要搜索多个记录字段。

下面是一个使用 INTERSECT 的示例查询,但我需要一个在 MySQL 中工作的查询。

SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john"
INTERSECT
SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith"

谢谢你的帮助。

4

7 回答 7

33

您可以使用内部联接来过滤在另一个表中具有匹配行的行:

SELECT DISTINCT records.id 
FROM records
INNER JOIN data d1 on d1.id = records.firstname AND data.value = "john"
INNER JOIN data d2 on d2.id = records.lastname AND data.value = "smith"

许多其他选择之一是in子句:

SELECT DISTINCT records.id 
FROM records
WHERE records.firstname IN (
    select id from data where value = 'john'
) AND records.lastname IN (
    select id from data where value = 'smith'
)
于 2010-02-19T23:35:37.660 回答
16

我认为这种方法更容易遵循,但是由于您最初加载了大量重复记录,因此会产生一些开销。我在一个大约有 10000-50000 条记录的数据库上使用它,并且通常与大约 5 个查询相交并且性能是可以接受的。

您所做的就是“UNION ALL”您想要相交的每个查询,并查看您每次得到哪些查询。

SELECT * From (

    (Select data1.* From data1 Inner Join data2 on data1.id=data2.id where data2.something=true)
    Union All
    (Select data1.* From data1 Inner Join data3 on data1.id=data3.id where data3.something=false)

) As tbl GROUP BY tbl.ID HAVING COUNT(*)=2 

因此,如果我们在两个查询中获得相同的记录,它的计数将为 2,并且最终的环绕查询将包含它。

于 2012-05-15T08:49:58.157 回答
5

改用连接:

SELECT records.id
FROM records
JOIN data AS D1 ON records.firstname = D1.id
JOIN data AS D2 ON records.lastname = D2.id
WHERE D1.value = 'john' and D2.value = 'smith'

下面是一些测试数据:

CREATE TABLE records (id INT NOT NULL, firstname INT NOT NULL, lastname INT NOT NULL);
INSERT INTO records (id, firstname, lastname) VALUES
(1, 1, 1),
(2, 1, 2),
(3, 2, 1),
(4, 2, 2);

CREATE TABLE data (id INT NOT NULL, value NVARCHAR(100) NOT NULL);
INSERT INTO data (id, value) VALUES
(1, 'john'),
(2, 'smith');

预期结果:

2

测试数据可能对张贴者没有用,但对于想要检查解决方案以查看其是否正常工作的选民或想要提交答案以便他们可以测试自己的答案的人可能有用。

于 2010-02-19T23:39:55.540 回答
2

我参加聚会有点晚了,但我认为完全模仿的最干净和最好的方法INTERSECT是:

SELECT * FROM
( SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john" ) x1
NATURAL JOIN
( SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith" ) x2
于 2020-09-21T23:23:26.977 回答
1

MYSQL 中 INTERSECT 的一般替代品是内连接:

SELECT DISTINCT * FROM 
(SELECT f1, f2, f3... FROM table1 WHERE f1>0)
INNER JOIN
(SELECT f1, f2, f3... FROM table2 WHERE f1>0)
USING(primary_key)

或者专门针对您的情况:

SELECT DISTINCT * FROM 
(SELECT records.id FROM records, data WHERE data.id = records.firstname AND data.value = "john") query1
INNER JOIN
(SELECT records.id FROM records, data WHERE data.id = records.lastname AND data.value = "smith") query2
USING (id)
于 2017-11-08T15:18:03.490 回答
1

SELECT t.id FROM table t WHERE NOT EXISTS (SELECT t2.id, FROM table2 t2 WHERE t2.id = t1.id)

https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html

于 2018-04-03T17:35:05.863 回答
0

由于 Mysql 不支持 INTERSECT,您可能有 2 种选择:inner joinin。这是in的解决方案:

SELECT records.id FROM records, data 
WHERE data.id = records.firstname AND data.value = "john"
    AND records.id in (SELECT records.id FROM records, data 
    WHERE data.id = records.lastname AND data.value = "smith);
于 2019-07-15T13:42:52.387 回答