按列值统计的 SQL 计数

huangapple go评论84阅读模式
英文:

SQL count by column values

问题

下面是你要翻译的内容:

I'm trying to count multiple values in multiple coluns in a table and I did that:

TABLE

id risk record api
1 OK OK NO
2 OK OK OK
3 OK OK OK
4 OK NO OK
5 NO OK NO

SQL:

  1. select 'risk' as nm_test, risk as tst_result, count(*) as qty
  2. from table
  3. group by risk
  4. union
  5. select 'record' as nm_test, record as tst_result, count(*) as qty
  6. from table
  7. group by record
  8. union
  9. select 'api' as nm_test, api as tst_result, count(*) as qty
  10. from table
  11. group by api

结果如下表所示:

nm_test tst_result qty
risk OK 4
risk NO 1
record OK 4
record NO 1
api OK 3
api NO 2

但是,相反地,我希望结果表格像这样旋转:

nm_test OK NO
risk 4 1
record 4 1
api 3 2

我尝试过,但是无法弄清楚窍门!任何帮助都将是宝贵的。

干杯。

英文:

I'm trying to count multiple values in multiple coluns in a table and I did that:

TABLE

id risk record api
1 OK OK NO
2 OK OK OK
3 OK OK OK
4 OK NO OK
5 NO OK NO

SQL:

  1. select 'risk' as nm_test, risk as tst_result, count(*) as qty
  2. from table
  3. group by risk
  4. union
  5. select 'record' as nm_test, record as tst_result, count(*) as qty
  6. from table
  7. group by record
  8. union
  9. select 'api' as nm_test, api as tst_result, count(*) as qty
  10. from table
  11. group by api

The result is the following table:

nm_test tst_result qty
risk OK 4
risk NO 1
record OK 4
record NO 1
api OK 3
api NO 2

But, instead, I would like to have the result table pivoted like this:

nm_test OK NO
risk 4 1
record 4 1
api 3 2

I tried to do that, but I was unable to figure out the trick! Any help would be valuable.

Cheers.

答案1

得分: 1

如果您有固定列要进行数据透视,值只有 'OK' 和 'NO',则:

  1. 选择 'risk' 作为 nm_test
  2. 计算(case risk = 'OK' 1 end) as 'OK',
  3. 计算(case risk = 'NO' 1 end) as 'NO'
  4. mytable
  5. 联合全部
  6. 选择 'record',
  7. 计算(case record = 'OK' 1 end),
  8. 计算(case record = 'NO' 1 end)
  9. mytable
  10. 联合全部
  11. 选择 'api',
  12. 计算(case api = 'OK' 1 end),
  13. 计算(case api = 'NO' 1 end)
  14. mytable
英文:

If you have a fixed columns to pivot, and values are 'OK' and 'NO' only then :

  1. select 'risk' as nm_test,
  2. count(case when risk = 'OK' then 1 end) as 'OK',
  3. count(case when risk = 'NO' then 1 end) as 'NO'
  4. from mytable
  5. union all
  6. select 'record',
  7. count(case when record = 'OK' then 1 end),
  8. count(case when record = 'NO' then 1 end)
  9. from mytable
  10. union all
  11. select 'api',
  12. count(case when api = 'OK' then 1 end),
  13. count(case when api = 'NO' then 1 end)
  14. from mytable

Demo here

答案2

得分: 0

尝试这个:

  1. SELECT
  2. nm_test,
  3. SUM(CASE WHEN tst_result = 'OK' THEN qty ELSE 0 END) AS OK,
  4. SUM(CASE WHEN tst_result = 'NO' THEN qty ELSE 0 END) AS NO
  5. FROM (
  6. SELECT 'risk' AS nm_test, risk AS tst_result, COUNT(*) AS qty
  7. FROM mytable
  8. GROUP BY risk
  9. UNION ALL
  10. SELECT 'record' AS nm_test, record AS tst_result, COUNT(*) AS qty
  11. FROM mytable
  12. GROUP BY record
  13. UNION ALL
  14. SELECT 'api' AS nm_test, api AS tst_result, COUNT(*) AS qty
  15. FROM mytable
  16. GROUP BY api
  17. ) subquery
  18. GROUP BY nm_test;
英文:

Try this:

  1. SELECT
  2. nm_test,
  3. SUM(CASE WHEN tst_result = 'OK' THEN qty ELSE 0 END) AS OK,
  4. SUM(CASE WHEN tst_result = 'NO' THEN qty ELSE 0 END) AS NO
  5. FROM (
  6. SELECT 'risk' AS nm_test, risk AS tst_result, COUNT(*) AS qty
  7. FROM mytable
  8. GROUP BY risk
  9. UNION ALL
  10. SELECT 'record' AS nm_test, record AS tst_result, COUNT(*) AS qty
  11. FROM mytable
  12. GROUP BY record
  13. UNION ALL
  14. SELECT 'api' AS nm_test, api AS tst_result, COUNT(*) AS qty
  15. FROM mytable
  16. GROUP BY api
  17. ) subquery
  18. GROUP BY nm_test;

答案3

得分: 0

忘记使用 UNION

在 PostgreSQL 中,从列到行的数据透视可以通过将数据转换为 jsonb 类型来完成。这在将来需要添加更多测试时会很有帮助。

  1. with pivot as (
  2. select j.*
  3. from mytable
  4. cross join lateral jsonb_each_text(to_jsonb(mytable) - 'id')
  5. as j(nm_test, tst_result)
  6. )
  7. select nm_test,
  8. count(*) filter (where tst_result = 'OK') as ok,
  9. count(*) filter (where tst_result = 'NO') as no
  10. from pivot
  11. group by nm_test;

使用 - id 可以从结果中去掉该列。

在聚合函数上使用 filter 可以将数据透视回列。这在可能的结果有限且已知的情况下非常有用。

工作示例

英文:

Forget using UNION.

Pivoting from columns to rows in PostgreSQL can be done by casting into and out of jsonb. This helps if you will be adding more tests in the future.

  1. with pivot as (
  2. select j.*
  3. from mytable
  4. cross join lateral jsonb_each_text(to_jsonb(mytable) - 'id')
  5. as j(nm_test, tst_result)
  6. )
  7. select nm_test,
  8. count(*) filter (where tst_result = 'OK') as ok,
  9. count(*) filter (where tst_result = 'NO') as no
  10. from pivot
  11. group by nm_test;

Using - id gets rid of that column from the results.

Using filter on the aggregates pivots back to columns. This is useful so long as the possible results are finite and known.

Working example.

huangapple
  • 本文由 发表于 2023年7月3日 23:07:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76606000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定