Есть ли способ выполнять операции над группами в SQL? - PullRequest
3 голосов
/ 17 апреля 2019

Так что я очень новичок в SQL и, вероятно, не описываю то, что я хочу сделать точно. У меня есть таблица с тремя столбцами, и я хочу сгруппировать по одному столбцу и посмотреть, какой процент каждой группы имеет определенное значение в другом столбце. Например, в таблице:

id   col1  col2
----------------
0       A     1
1       A     2
2       B     2
3       B     2
4       A     1

Я бы хотел сгруппировать по col1 и посмотреть, какой процент каждой группы (A или B) имеет значение 1 в col2. Результат, который я хочу получить от этого:

col1  percentage_col2_equals_1
------------------------------
   A                      66.7
   B                       0.0

Пока у меня есть:

SELECT col1,
((SELECT COUNT(*) FROM my_table
WHERE col2 = 1
GROUP BY col1) / 
(SELECT COUNT(*) FROM my_table
GROUP BY col1) * 100)
FROM my_table
GROUP BY col1;

Но это не работает. Любая помощь будет оценена!

Ответы [ 6 ]

1 голос
/ 17 апреля 2019

Тот же ответ, что и у всех, просто поместите это здесь из-за выразительности Postgres:)

Живой тест: https://www.db -fiddle.com / f / goL488VaPuZYii7Wik3pFk / 4

select
    col1,
    count(*) filter(where col2 = 1) ::numeric / count(*)

from tbl    
group by col1;

Вывод:

| col1 | ?column?               |
| ---- | ---------------------- |
| A    | 0.66666666666666666667 |
| B    | 0.00000000000000000000 |

Чтобы представить его в процентах с 1 десятичным знаком, умножьте его на 100 и округлите до 1:

Живой тест: https://www.db -fiddle.com / f / goL488VaPuZYii7Wik3pFk / 5

select
    col1,    
    round( 
      count(*) filter(where col2 = 1) ::numeric / count(*) * 100, 
      1 
    ) as p_a      
from tbl    
group by col1;


select
    col1,    
    (
        count(*) filter(where col2 = 1) ::numeric / count(*) * 100
    )::numeric(100,1) as p_b       
from tbl    
group by col1;

Вывод:

| col1 | p_a  |
| ---- | ---- |
| A    | 66.7 |
| B    | 0.0  |


| col1 | p_b  |
| ---- | ---- |
| A    | 66.7 |
| B    | 0.0  |
1 голос
/ 17 апреля 2019

использование case when

SELECT col1,(coalesce(count(case when col2=1 then col2 end),0)*100.00)/count(*)
from tablename
group by col1
0 голосов
/ 17 апреля 2019

В SQLite выражение col2 = 1 возвращает 1 при true и 0 при false.
Так что вам просто нужно среднее значение col2 = 1, а затем округлите его до 1 десятичного знака:

select
  col1,
  round(100.0 * avg(col2 = 1), 1) percentage_col2_equals_1
from tablename  
group by col1

См. Демоверсию .
Результаты:

| col1 | percentage_col2_equals_1 |
| ---- | ------------------------ |
| A    | 66.7                     |
| B    | 0                        |
0 голосов
/ 17 апреля 2019

это будет работать:

CREATE TABLE Table1
    ("id" int, "col1" varchar2(1), "col2" int)
;
//do inserts
select aa."col1",((select count(*) from Table1 b 
where b."col1"=aa."col1" and b."col2"=1 )*100/(select count(*) 
from Table1 c where c."col1"='A' )) percentge
from Table1 aa
group by aa."col1"
; 

вывод:

A   66.66666666666666666666666666666666666667
B   0
0 голосов
/ 17 апреля 2019
     CREATE TABLE #TEMP
    (ID   INT, 
     COL1 VARCHAR(10), 
     COL2 INT
    );
    INSERT INTO #TEMP
           SELECT 0, 'A',1
           UNION
           SELECT 1, 'A',2
           UNION
           SELECT 2, 'B',2
           UNION
           SELECT 3, 'B',2
           UNION
           SELECT 4, 'A',1;
    SELECT T.COL1, 
           ROUND((CAST(COUNT(CASE
                                 WHEN T.COL2 = 1
                                 THEN T.COL2
                                 ELSE NULL
                             END) AS DECIMAL) / (S.COL2)) * 100.0, 2) AS Percentage_1
    FROM #TEMP T
         JOIN
    (
        SELECT COUNT(COL2) COL2, 
               COL1
        FROM #TEMP
        GROUP BY COL1
    ) S ON S.COL1 = T.COL1
    GROUP BY T.COL1, 
             S.COL2;
0 голосов
/ 17 апреля 2019

Следующий запрос вернет ожидаемый результат:

SELECT col1, 
       CAST(((SUM(IIF(col2 = 1, 1, 0))) * 100.0) / COUNT(*) AS DECIMAL(5, 1)) AS percentage_col2_equals_1
FROM my_table
GROUP BY col1;

Выполнение образца с данными образца:

DECLARE @my_table TABLE (id INT,  col1 CHAR(1),  col2 INT);

INSERT INTO @my_table (id, col1, col2) VALUES
(0, 'A', 1),
(1, 'A', 2),
(2, 'B', 2),
(3, 'B', 2),
(4, 'A', 1);

SELECT col1, CAST(((SUM(IIF(col2 = 1, 1, 0))) * 100.0) / COUNT(*) AS DECIMAL(5, 1)) AS percentage_col2_equals_1
FROM @my_table
GROUP BY col1;

Вывод:

col1    percentage_col2_equals_1
---------------------------------
A       66.7
B       0.0
...