You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化查询同一ID下存在不同值列的SQL语句

优化多列差异检测的SQL查询

原查询通过多次GROUP BY结合UNION实现需求,但这种方式会对原表进行多次全表扫描,当数据量较大时性能会显著下降。以下是几种更高效的优化方案:

方案1:一次分组后通过数组转多行(适用于PostgreSQL、BigQuery等)

先对ID分组,一次性计算所有列的差异状态,再通过数组函数将有差异的列转为行记录,仅需扫描原表一次:

SELECT 
    t.ID,
    unnest(array_remove(array['Brand', 'Type'], NULL)) AS Discrepancy
FROM (
    SELECT 
        ID,
        CASE WHEN COUNT(DISTINCT Brand) > 1 THEN 'Brand' ELSE NULL END AS brand_diff,
        CASE WHEN COUNT(DISTINCT Type) > 1 THEN 'Type' ELSE NULL END AS type_diff
    FROM table
    GROUP BY ID
) t
WHERE brand_diff IS NOT NULL OR type_diff IS NOT NULL

方案2:使用UNPIVOT(适用于SQL Server、Oracle等)

利用数据库内置的行转列函数UNPIVOT,基于一次分组的结果生成差异列记录:

SELECT ID, Discrepancy
FROM (
    SELECT 
        ID,
        CASE WHEN COUNT(DISTINCT Brand) > 1 THEN 1 ELSE 0 END AS Brand,
        CASE WHEN COUNT(DISTINCT Type) > 1 THEN 1 ELSE 0 END AS Type
    FROM table
    GROUP BY ID
) src
UNPIVOT (
    HasDiscrepancy FOR Discrepancy IN (Brand, Type)
) unpvt
WHERE HasDiscrepancy = 1

方案3:通用CTE+UNION ALL

通过CTE先完成一次分组计算所有列的差异计数,再用UNION ALL生成结果,相比原方案减少了表扫描次数:

WITH grouped AS (
    SELECT 
        ID,
        COUNT(DISTINCT Brand) AS brand_distinct,
        COUNT(DISTINCT Type) AS type_distinct
    FROM table
    GROUP BY ID
)
SELECT ID, 'Brand' AS Discrepancy FROM grouped WHERE brand_distinct > 1
UNION ALL
SELECT ID, 'Type' AS Discrepancy FROM grouped WHERE type_distinct > 1

额外优化建议

  • 替换UNION为UNION ALL:原查询中UNION会自动去重,但不同列的Discrepancy值唯一,无需去重,UNION ALL性能更优。
  • 添加复合索引:针对(ID, Brand)、(ID, Type)创建复合索引,可加速COUNT(DISTINCT)的计算,避免回表查询。

内容的提问来源于stack exchange,提问作者CCM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:32:51