我有一个以逗号分隔的ID列表,我必须在mysql(Percona Xtra DB)中的IN()
子句中使用,类似于:
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次?
答案 0 :(得分:1)
这不能用IN ()
谓词完成。这只会检查给定行是否满足谓词;它不会复制"返回的行。
获得"重复"返回的行(因此值可以在SUM()聚合中累积),您需要另一个行源。
一种选择是对内联视图使用JOIN操作,而不是IN()
列表谓词。
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
另一个(可能更有效)选项(如果有很多重复值)将使用" count"而不是重复这些值,并乘以,例如
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)
因为,对于每一行,这两个谓词都将评估为TRUE
,FALSE
或NULL
。没有办法返回"次数"与IN()
比较相匹配的商品。