MySql IN 子句,试图匹配元组的 IN 列表
Posted
技术标签:
【中文标题】MySql IN 子句,试图匹配元组的 IN 列表【英文标题】:MySql IN clauses, trying to match IN list of tuples 【发布时间】:2014-09-17 10:32:23 【问题描述】:我正在尝试根据三列的匹配来选择重复记录。三元组的列表可能很长(1000 个),所以我想简明扼要。
当我有一个大小为 10(已知重复)的列表时,它只匹配 2 个(看似随机的)而错过了其他 8 个。我希望返回 10 条记录,但只看到 2 条。
我已经把它缩小到这个问题:
这将返回一条记录。预期 2:
select *
from ali
where (accountOid, dt, x) in
(
(64, '2014-03-01', 10000.0),
(64, '2014-04-23', -122.91)
)
按预期返回两条记录:
select *
from ali
where (accountOid, dt, x) in ( (64, '2014-03-01', 10000.0) )
or (accountOid, dt, x) in ( (64, '2014-04-23', -122.91) )
知道为什么第一个查询只返回一条记录吗?
【问题讨论】:
我无法在我的机器上重现该问题(mysql 5.6.14)。你会做一个小提琴吗? 您能否编辑您的问题并描述列的数据类型 (SHOW CREATE TABLE ali
)?如果您对列x
使用FLOAT
或DOUBLE
,则可能会导致相等比较失败,因为精确值以意想不到的方式四舍五入。还请具体说明您使用的 MySQL 版本。
你能贴出你正在使用的代码吗?我将它复制到一个表中,起初它看起来像是一个操作数值,但这是我缺少括号集的错。像 Vatev 我无法重现问题
不知道如何让它成为一个小提琴。我已将查询更改为使用: (a,b,c) = (...) or (a,b,c) = () or (a,b,c) = () ... 不理想我知道,但它有效。当我有更多时间时,我会发布代码。感谢您的关注。
google for sql fiddle (sqlfiddle.com),它是一个发布和测试 SQL 的平台。或者只是在这里发布您的表创建语句。
【参考方案1】:
我建议您不要为此使用 IN(),而是使用 where exists 查询,例如:
CREATE TABLE inlist
(`id` int, `accountOid` int, `dt` datetime, `x` decimal(18,4))
;
INSERT INTO inlist
(`id`, `accountOid`, `dt`, `x`)
VALUES
(1, 64, '2014-03-01 00:00:00', 10000.0),
(2, 64, '2014-04-23 00:00:00', -122.91)
;
select *
from ali
where exists ( select null
from inlist
where ali.accountOid = inlist.accountOid
and ali.dt = inlist.dt
and ali.x = inlist.x
)
;
我能够重现一个问题(比较 http://sqlfiddle.com/#!2/7d2658/6 到 http://sqlfiddle.com/#!2/fe851/1 两者都是 MySQL 5.5.3),如果 x 列是数字并且值是负数,则使用 IN() 不匹配,但当任一数字时匹配或十进制使用表格和存在的地方。
也许不是一个决定性的测试,但我个人无论如何都不会使用 IN() 。
为什么不这样确定重复项?
select
accountOid
, dt
, x
from ali
group by
accountOid
, dt
, x
having
count(*) > 1
然后将其用作 where exists 条件中的派生表:
select *
from ali
where exists (
select null
from (
select
accountOid
, dt
, x
from ali
group by
accountOid
, dt
, x
having
count(*) > 1
) as inlist
where ali.accountOid = inlist.accountOid
and ali.dt = inlist.dt
and ali.x = inlist.x
)
请参阅http://sqlfiddle.com/#!2/ede292/1 以了解上面的查询
【讨论】:
inner join syntax would seem simpler 给我。我也希望连接同样有效,尽管根据 SQL Fiddle 的说法,查询计划确实不同,我不太擅长解释这些。 是的,好点,使用同一个派生表的内连接也是一种选择。 sqlfiddle 的执行计划通常没有那么重要,因为没有索引并且数据规模太小 - 但两种方法没有太大区别。以上是关于MySql IN 子句,试图匹配元组的 IN 列表的主要内容,如果未能解决你的问题,请参考以下文章