我正在尝试根据三列的匹配来选择重复记录。三元组的列表可能很长 (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) )
知道为什么第一个查询只返回一条记录吗?
最佳答案
我建议您不要为此使用 IN(),而是使用存在的查询,例如:
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对于上面的查询
关于MySql IN 子句,试图匹配 IN 元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24957948/