MySql,其中..在多个列中

MySql,其中..在多个列中,mysql,sql,Mysql,Sql,我需要在MySql中实现以下查询 SELECT name, value FROM opponent WHERE name in (SELECT name FROM noc WHERE fictive_status='fictional') AND value in (SELECT name FROM noc WHERE fictive_status='fictional') 我需要在另一个表noc中查找其虚拟_状态(对于两者)为“虚构”的表中的所有行(名称、值(其他名称)) 试用 SELE

我需要在MySql中实现以下查询

SELECT name, value FROM opponent 
WHERE name in (SELECT name FROM noc WHERE fictive_status='fictional') 
AND value in (SELECT name FROM noc WHERE fictive_status='fictional')
我需要在另一个表noc中查找其虚拟_状态(对于两者)为“虚构”的表中的所有行(名称、值(其他名称))

试用

SELECT name, value from opponent WHERE(name,value) in (SELECT name FROM noc WHERE fictive_status='fictional')
它需要2列操作数和

Select name, value from opponent where (name and value) in (select name from noc where fictive_status='fictional')
这将返回对手表中的所有行


如何才能更好地实施?

请鼓轮滚动。您可以通过以下方式在MySQL中实现:

SELECT o.name, o.value
FROM opponent o
WHERE o.name in (SELECT noc.name FROM noc WHERE noc.fictive_status = 'fictional') and
      o.value in (SELECT noc.name FROM noc WHERE noc.fictive_status = 'fictional');

这实际上是带有列别名的查询。没有先验的理由去改变它。查询使用ANSI标准SQL,几乎可以在任何数据库中使用。

像您这样使用两个子查询效率很低,因为MySQL必须为每个子查询生成一个大型临时表,存储noc中的任何名称。这是一张大临时桌

相反,我建议您使用
JOIN

SELECT DISTINCT o.name, o.value 
FROM opponent AS o 
JOIN noc AS n1 ON n1.fictive_status='fictional' AND n1.name = o.name
JOIN noc AS n2 ON n2.fictive_status='fictional' AND n2.name = o.value
如果您在
noc(虚拟状态,名称)
上有正确的索引,那么这不会很昂贵。它不会扫描整个表,它只搜索匹配的行


区别在于,如果在noc中有多个匹配项,则减少结果集。

您可以将以下内容与
EXISTS

 SELECT o.name, o.value 
    FROM opponent AS o 
    WHERE EXISTS
    (
      SELECT * FROM noc As n1 WHERE n1.name = o.name  AND n1.fictive_status='fictional'
    )
    AND EXISTS
    (
       SELECT * FROM noc As n1 WHERE n1.name = o.value   AND n1.fictive_status='fictional'
    ) 

你原来的查询有什么问题?看起来不对,不是吗?我查询表noc两次,它们完全相同。我可以查询noc表一次并使用它从对手表中查找名称和值吗?我觉得您的查询非常完美。应该是直截了当的。你必须查表两次;这没什么问题。MySQL曾经在子句中的
方面非常薄弱,您会使用
EXISTS
子句来规避这个问题,但我想这已经是过去的事了。在
中使用
和存在
的两个查询应产生完全相同的执行计划。对于完全相同的数据,两次查询noc不是很麻烦吗?@ShashankShekhar。从一个工作查询开始。如果查询速度慢,请担心优化问题。你可以问另一个问题,如果这是你关心的问题,因为在这个问题中没有提到。n1.name怎么可能等于o.name,也等于o.value,这不会产生任何结果这仍然不够有效。有2个子查询将生成2个临时表,我认为这与我的原始查询一样昂贵。加入似乎是答案。