Sql 对于具有唯一列的表,如何计算多个列的特定值

Sql 对于具有唯一列的表,如何计算多个列的特定值,sql,snowflake-cloud-data-platform,Sql,Snowflake Cloud Data Platform,如果我有一张像这样的桌子: u_id A B C D ---------------------------------- jud 1 1 0 1 bud 0 0 1 0 cud 1 1 0 1 nud 0 0 1 0 dud 1 0 0 1 aud 0 1 1 0 fud 1 0 1 1 以下哪种sql可用于获得输出: coun

如果我有一张像这样的桌子:

u_id    A   B   C   D
----------------------------------
jud     1   1   0   1
bud     0   0   1   0
cud     1   1   0   1
nud     0   0   1   0
dud     1   0   0   1
aud     0   1   1   0
fud     1   0   1   1
以下哪种sql可用于获得输出:

    count  0    count 1
-----------------------
A          3    4
B          4    3
C          3    4
D          3    4
行或列不重要,只需要表中多个列的特定值计数

它可以是特定的字符串值,也可以是“是”或“否”,而不是0和1


谢谢

使用
UNION ALL
和聚合。假设列中唯一可能的值是
0
1

SELECT 'A' col, COUNT(*) - SUM(A) count0, SUM(A) count1 FROM mytable
UNION ALL SELECT 'B', COUNT(*) - SUM(B), SUM(B) FROM mytable
UNION ALL SELECT 'C', COUNT(*) - SUM(C), SUM(C) FROM mytable
UNION ALL SELECT 'D', COUNT(*) - SUM(D), SUM(D) FROM mytable

| col | count0 | count1 |
| --- | ------ | ------ |
| A   | 3      | 4      |
| B   | 4      | 3      |
| C   | 3      | 4      |
| D   | 3      | 4      |
如果可以使用
0
/
1
以外的其他值,则可以将
选择
s更改为,例如
'yes'
/
'no'
,然后:

SELECT 
    'A' col, 
    SUM(CASE WHEN A = 'no'  THEN 1 ELSE 0 END) count_no,
    SUM(CASE WHEN A = 'yes' THEN 1 ELSE O END) count_yes
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'B' col, 
    SUM(CASE WHEN B = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN B = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'C' col, 
    SUM(CASE WHEN C = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN C = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'D' col, 
    SUM(CASE WHEN D = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN D = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col

使用
UNION ALL
和聚合。假设列中唯一可能的值是
0
1

SELECT 'A' col, COUNT(*) - SUM(A) count0, SUM(A) count1 FROM mytable
UNION ALL SELECT 'B', COUNT(*) - SUM(B), SUM(B) FROM mytable
UNION ALL SELECT 'C', COUNT(*) - SUM(C), SUM(C) FROM mytable
UNION ALL SELECT 'D', COUNT(*) - SUM(D), SUM(D) FROM mytable

| col | count0 | count1 |
| --- | ------ | ------ |
| A   | 3      | 4      |
| B   | 4      | 3      |
| C   | 3      | 4      |
| D   | 3      | 4      |
如果可以使用
0
/
1
以外的其他值,则可以将
选择
s更改为,例如
'yes'
/
'no'
,然后:

SELECT 
    'A' col, 
    SUM(CASE WHEN A = 'no'  THEN 1 ELSE 0 END) count_no,
    SUM(CASE WHEN A = 'yes' THEN 1 ELSE O END) count_yes
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'B' col, 
    SUM(CASE WHEN B = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN B = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'C' col, 
    SUM(CASE WHEN C = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN C = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col
UNION ALL SELECT 
    'D' col, 
    SUM(CASE WHEN D = 'no'  THEN 1 ELSE 0 END),
    SUM(CASE WHEN D = 'yes' THEN 1 ELSE 0 END)
FROM mytable
GROUP BY col

如果您对单行没有问题,可以执行以下操作:

select sum(a), sum(1-a), sum(b), sum(1-b), sum(c), sum(1-c), sum(d), sum(1-d)
from t;
这种方法的优点是
t
只读取一次。如果它是一个复杂的视图,则更是如此

记住这一点,您可以取消Pivot此结果:

select v.x,
       (case when v.x = 'a' then a_0 end) as a_0,
       (case when v.x = 'a' then a_1 end) as a_1,
       (case when v.x = 'b' then b_0 end) as b_0,
       (case when v.x = 'b' then b_1 end) as b_1,
       (case when v.x = 'c' then c_0 end) as c_0,
       (case when v.x = 'c' then c_1 end) as c_1,
       (case when v.x = 'd' then d_0 end) as d_0,
       (case when v.x = 'd' then d_1 end) as d_1
from (select sum(a) as a_1, sum(1-a) as a_0, 
             sum(b) as b_1, sum(1-b) as b_0, 
             sum(c) as c_1, sum(1-c) as c_0, 
             sum(d) as d_1, sum(1-d) as d_0 
      from t
     ) s cross join
     (values ('a'), ('b'), ('c'), ('d')) v(x)  -- may require a subquery

如果您对单行没有问题,可以执行以下操作:

select sum(a), sum(1-a), sum(b), sum(1-b), sum(c), sum(1-c), sum(d), sum(1-d)
from t;
这种方法的优点是
t
只读取一次。如果它是一个复杂的视图,则更是如此

记住这一点,您可以取消Pivot此结果:

select v.x,
       (case when v.x = 'a' then a_0 end) as a_0,
       (case when v.x = 'a' then a_1 end) as a_1,
       (case when v.x = 'b' then b_0 end) as b_0,
       (case when v.x = 'b' then b_1 end) as b_1,
       (case when v.x = 'c' then c_0 end) as c_0,
       (case when v.x = 'c' then c_1 end) as c_1,
       (case when v.x = 'd' then d_0 end) as d_0,
       (case when v.x = 'd' then d_1 end) as d_1
from (select sum(a) as a_1, sum(1-a) as a_0, 
             sum(b) as b_1, sum(1-b) as b_0, 
             sum(c) as c_1, sum(1-c) as c_0, 
             sum(d) as d_1, sum(1-d) as d_0 
      from t
     ) s cross join
     (values ('a'), ('b'), ('c'), ('d')) v(x)  -- may require a subquery

您没有提到您正在使用的数据库,但在Oracle中,您可以同时使用
解码
计数
,以使其合理干净:

SELECT 'A' AS FIELD_NAME,
            COUNT(DECODE(A, 0, 0, NULL)) AS ZERO_COUNT,
            COUNT(DECODE(A, 0, NULL, A)) AS NON_ZERO_COUNT
  FROM TEST_TABLE UNION ALL
SELECT 'B', COUNT(DECODE(B, 0, 0, NULL)),
            COUNT(DECODE(B, 0, NULL, A))
  FROM TEST_TABLE UNION ALL
SELECT 'C', COUNT(DECODE(C, 0, 0, NULL)),
            COUNT(DECODE(C, 0, NULL, A))
  FROM TEST_TABLE UNION ALL
SELECT 'D', COUNT(DECODE(D, 0, 0, NULL)),
            COUNT(DECODE(D, 0, NULL, A))
  FROM TEST_TABLE

您没有提到您正在使用的数据库,但在Oracle中,您可以使用
解码
计数
来合理地清理:

SELECT 'A' AS FIELD_NAME,
            COUNT(DECODE(A, 0, 0, NULL)) AS ZERO_COUNT,
            COUNT(DECODE(A, 0, NULL, A)) AS NON_ZERO_COUNT
  FROM TEST_TABLE UNION ALL
SELECT 'B', COUNT(DECODE(B, 0, 0, NULL)),
            COUNT(DECODE(B, 0, NULL, A))
  FROM TEST_TABLE UNION ALL
SELECT 'C', COUNT(DECODE(C, 0, 0, NULL)),
            COUNT(DECODE(C, 0, NULL, A))
  FROM TEST_TABLE UNION ALL
SELECT 'D', COUNT(DECODE(D, 0, 0, NULL)),
            COUNT(DECODE(D, 0, NULL, A))
  FROM TEST_TABLE

谢谢,如果值不是数字而是唯一的字符串,如“是”和“否”,该怎么办?我们如何计算“是”和“否”的数量?谢谢,但在snowflake中,以“A”表示的错误不是有效的group by表达式。@GMB这太棒了!感谢您的帮助,如果您感兴趣,Snowflake社区有一个Select Star程序,可为您的个人资料添加点数。如果您是注册Snowflake用户,请查看页面并注册(如果您感兴趣):谢谢,如果值不是数字而是唯一的字符串,如“是”和“否”,该怎么办?我们如何计算“是”和“否”的数量?谢谢,但在snowflake中,以“A”表示的错误不是有效的group by表达式。@GMB这太棒了!感谢您的帮助,如果您感兴趣,Snowflake社区提供了Select Star计划,可为您的个人资料添加点数。如果您是注册Snowflake用户,请查看该页面,如果您感兴趣,请注册: