Mysql WHERE IN()子句必须对重复出现的次数求和

Mysql WHERE IN()子句必须对重复出现的次数求和,mysql,Mysql,我在mysql(Percona Xtra DB)中的IN()子句中有一个逗号分隔的ID列表,类似于: SELECT sum(p_views) as total_views FROM table WHERE id IN (1,1,3,5,5,5,7) 在上面的示例中,ID 1和5将只求和一次,而不是实际出现的次数。重复项的数量未知,范围从2到20000 我如何让mysql将它们视为唯一的数字,并相应地将它们相加,无论它们是否都是唯一的,或者列表是否由单个ID组成,20000次 这不能用IN()谓

我在mysql(Percona Xtra DB)中的
IN()
子句中有一个逗号分隔的ID列表,类似于:

SELECT sum(p_views) as total_views FROM table WHERE id IN (1,1,3,5,5,5,7)
在上面的示例中,ID 1和5将只求和一次,而不是实际出现的次数。重复项的数量未知,范围从2到20000


我如何让mysql将它们视为唯一的数字,并相应地将它们相加,无论它们是否都是唯一的,或者列表是否由单个ID组成,20000次

这不能用
IN()
谓词来完成。只检查给定行是否满足谓词;它不会“复制”返回的行

要获取返回的“重复”行(以便可以在SUM()聚合中累积值),需要另一个行源

一个选项是对内联视图使用联接操作,而不是()中的
IN
list谓词

SELECT SUM(t.p_views) AS total_views
  FROM table t
  JOIN 
     ( SELECT           1 AS id 
       UNION ALL SELECT 1
       UNION ALL SELECT 1
       UNION ALL SELECT 3
       UNION ALL SELECT 5
       UNION ALL SELECT 5
       UNION ALL SELECT 5
       UNION ALL SELECT 7
     ) c
    ON c.id = t.id
另一个(可能更有效的)选择(如果有很多重复的值)是使用“计数”代替重复的值,并进行乘法,例如

SELECT SUM(t.p_views*c.cnt) AS total_views
  FROM table t
  JOIN
     ( SELECT           1 AS id, 2 AS cnt 
       UNION ALL SELECT 3      , 1
       UNION ALL SELECT 5      , 3
       UNION ALL SELECT 7      , 1
     ) c
    ON c.id = t.id
如果此信息已在另一行源中可用,则可以通过在查询中使用该行源(如果有适当的索引可用)来提高性能,并避免生成混乱的“硬编码”UNION ALL内联视图,该视图不会被索引(除非Percona已经为内联视图实现了索引。)

我相信还有其他方法

但归根结底,它不能用
IN()
列表谓词来完成。使用此谓词的查询结果:

WHERE id IN (1)
WHERE id IN (1,1,1,1)
将与以下查询的结果相同:

WHERE id IN (1)
WHERE id IN (1,1,1,1)

因为,对于每一行,这两个谓词都将计算为
TRUE
FALSE
NULL
。无法返回()中与
匹配的项的“次数”
比较。

如果您已经多次拥有相同的ID,那么您甚至不需要运行另一个查询的可能性有多大?为什么不从您开始的位置对它们进行汇总?运行该查询将完成什么?如何使用ID和事件构建一个临时表,并使用此临时表Y连接您的表然后你可以
sum(t.p_视图*tt.occurrences)
。每个ID都附加了一个into。我需要将该列与ID列表中显示的列相加多少次才能获得准确的数据。如果我使用临时表,我可能会使用我最初使用的联接。我希望避免联接。为什么要避免联接?大多数情况下,使用联接是一个非常好的主意。是的,我是噢,工会解决方案,非常混乱。我必须务实地构建这些,在某些情况下,它将是数百/数千个工会展示你在“构建”什么这些?您有可以提供此信息的行源吗?我认为
JOIN
操作才是真正的方法,只需检查
EXPLAIN
输出,并确保有合适的索引可用。(由于有数千个
UNION-ALL-SELECT
,听起来您可能会遇到SQL语句的
max\u-allowed\u数据包
限制。在这种情况下,请回到JOIN查询。感谢您的澄清。