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

如何将多列值计数的SQL查询结果进行转置(Pivot)?

行转列实现方案

你的需求本质是行转列(Pivot),把纵向的分组统计结果转换成横向的行列结构。下面提供几种通用和数据库专属的实现方法,直接替换你的表名即可使用:

通用方案:条件聚合(兼容所有主流数据库)

这是最稳妥的方式,不需要依赖数据库特定函数,用CASE WHEN配合聚合函数直接统计各状态数量:

假设你的原表中,risk、record、api是三个独立的状态字段(比如每行有risk_status、record_status、api_status),可以这样写:

SELECT
    'risk' AS nm_test,
    COUNT(CASE WHEN risk_status = 'OK' THEN 1 END) AS OK_count,
    COUNT(CASE WHEN risk_status = 'NO' THEN 1 END) AS NO_count
FROM your_table
UNION ALL
SELECT
    'record' AS nm_test,
    COUNT(CASE WHEN record_status = 'OK' THEN 1 END) AS OK_count,
    COUNT(CASE WHEN record_status = 'NO' THEN 1 END) AS NO_count
FROM your_table
UNION ALL
SELECT
    'api' AS nm_test,
    COUNT(CASE WHEN api_status = 'OK' THEN 1 END) AS OK_count,
    COUNT(CASE WHEN api_status = 'NO' THEN 1 END) AS NO_count
FROM your_table;

如果是同一个status字段对应不同的测试类型(比如通过test_type字段区分risk/record/api),可以简化成单表聚合:

SELECT
    test_type AS nm_test,
    COUNT(CASE WHEN status = 'OK' THEN 1 END) AS OK_count,
    COUNT(CASE WHEN status = 'NO' THEN 1 END) AS NO_count
FROM your_table
WHERE test_type IN ('risk', 'record', 'api')
GROUP BY test_type;

数据库专属方案(简化代码)

如果你的数据库支持行转列专属函数,可以用更简洁的语法:

MySQL 8.0+/MariaDB 10.3+:PIVOT语法

WITH test_stats AS (
    SELECT 'risk' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
    UNION ALL
    SELECT 'record' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
    UNION ALL
    SELECT 'api' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
)
SELECT nm_test, `OK`, `NO`
FROM test_stats
PIVOT (SUM(cnt) FOR status IN (`OK`, `NO`)) AS pivot_result;

PostgreSQL:crosstab函数

需要先启用tablefunc扩展,再进行行转列:

CREATE EXTENSION IF NOT EXISTS tablefunc;

SELECT *
FROM crosstab(
    'SELECT nm_test, status, COUNT(*) AS cnt
     FROM (
         SELECT ''risk'' AS nm_test, status FROM your_table
         UNION ALL
         SELECT ''record'' AS nm_test, status FROM your_table
         UNION ALL
         SELECT ''api'' AS nm_test, status FROM your_table
     ) AS combined_data
     GROUP BY nm_test, status
     ORDER BY nm_test, status',
    'VALUES (''OK''), (''NO'')'
) AS final_result(nm_test text, ok_count int, no_count int);

SQL Server:PIVOT语法

WITH test_stats AS (
    SELECT 'risk' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
    UNION ALL
    SELECT 'record' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
    UNION ALL
    SELECT 'api' AS nm_test, status, COUNT(*) AS cnt
    FROM your_table GROUP BY nm_test, status
)
SELECT nm_test, [OK], [NO]
FROM test_stats
PIVOT (SUM(cnt) FOR status IN ([OK], [NO])) AS pivot_result;

关键注意点

  • 如果status字段除了OK/NO还有其他值,需要在CASE WHEN或PIVOT中补充枚举,或者用WHERE过滤掉无关值。
  • 条件聚合方案兼容性最强,适合跨数据库场景;专属函数方案代码更简洁,但依赖数据库版本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:47:42