我有两张表,记录和数据。记录有多个字段(名字,姓氏等)。这些字段中的每一个都是存储实际值的数据表的外键。我需要搜索多个记录字段。
以下是使用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"
感谢您的帮助。
答案 0 :(得分:26)
您可以使用内部联接来筛选在另一个表中具有匹配行的行:
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'
)
答案 1 :(得分:11)
我认为这种方法更容易理解,但由于您最初加载了大量重复记录,因此会产生一些开销。我在具有大约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,最终的环绕查询将包含它。
答案 2 :(得分: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
测试数据可能对海报没有用,但对于想要检查解决方案以确定其工作正常的选民,或者想要提交答案以便他们可以测试自己答案的人来说,可能会有用。
答案 3 :(得分: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)
答案 4 :(得分: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
答案 5 :(得分:0)
由于Mysql不支持INTERSECT,因此您可能有两种选择:内部联接和 in 。这是 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);
答案 6 :(得分:0)
我参加聚会有点晚了,但是我认为完全模仿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