SQL添加INNER JOIN后COUNT统计结果从1变为49的原因及解决方法
问题原因
- JOIN操作放大了中间结果集行数:
Campaign表中CampaignId = 24896对应存在49条记录,Track_Click_7表的每条记录关联时会匹配到这49条Campaign数据,导致JOIN后的中间结果中每个LinkId对应49行数据。 - 窗口函数计算优先级高于DISTINCT:
COUNT(*) OVER ()类的窗口函数是在SQL执行的窗口计算阶段完成,早于最终的DISTINCT去重步骤,因此统计的是JOIN后放大的行数,去重不会改变已经计算好的统计值。
修复方案
最优解法是先完成点击数据的统计,再关联Campaign表取URL字段,完全避免关联操作影响统计结果,参考代码如下:
SELECT t.LinkId [Index], c.Link, t.Clicks, t.[Percent] FROM ( -- 先独立完成点击表的统计逻辑 SELECT DISTINCT LinkId, COUNT(*) OVER (PARTITION BY LinkId) [Clicks], CONVERT(VARCHAR(10), COUNT(*) OVER (PARTITION BY LinkId) * 100 / COUNT(*) OVER (PARTITION BY 1)) + '%' [Percent] FROM Track_Click_7 WHERE CampaignId = 24896 ) t -- 统计完成后再关联获取链接信息,关联前先对Campaign表去重避免重复行 INNER JOIN ( SELECT DISTINCT CampaignId, Link FROM Campaign WHERE CampaignId = 24896 ) c ON t.CampaignId = c.CampaignId
如果确认同CampaignId下所有Link字段值完全一致,也可以直接修改原SQL的窗口计数逻辑为COUNT(DISTINCT Track_Click_7.主键字段) OVER (PARTITION BY Track_Click_7.LinkId),但性能会弱于先统计后关联的写法。
内容的提问来源于stack exchange,提问作者Matt Ferebee
相关产品推荐
相关产品推荐

