как у нас есть счетчик определенных значений для нескольких столбцов с таблицей, имеющей уникальный столбец - PullRequest
1 голос
/ 20 сентября 2019

Если у меня есть таблица типа:

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 это могут быть конкретные строковые значения, а также 'да' или 'нет'

Спасибо

Ответы [ 3 ]

0 голосов
/ 20 сентября 2019

Если у вас все в порядке с одной строкой, вы можете сделать:

select sum(a), sum(1-a), sum(b), sum(1-b), sum(c), sum(1-c), sum(d), sum(1-d)
from t;

Преимущество этого подхода в том, что t читается только один раз.Это еще более верно, если это сложное представление.

Имея это в виду, вы можете отключить этот результат:

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
0 голосов
/ 20 сентября 2019

Вы не упоминаете базу данных, которую используете, но в Oracle вы можете использовать DECODE и COUNT вместе, чтобы сделать это достаточно чистым:

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

dbfiddle здесь

0 голосов
/ 20 сентября 2019

Используйте 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

Демонстрация на DB Fiddle :

| col | count0 | count1 |
| --- | ------ | ------ |
| A   | 3      | 4      |
| B   | 4      | 3      |
| C   | 3      | 4      |
| D   | 3      | 4      |

Если возможны другие значения, отличные от 0 / 1, то вы можете изменить SELECT 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
...