Я работаю с SQL-версией, созданной data.world, которая кажется довольно универсальной (возможно, версией MySql)
мои данные выглядят так:
ID |SSM | Abortion | Climate |
1 High Low Medium
2 High High Lo
3 Low High High
4 Medium Low Low
Я хочу сгенерировать инструкцию SQL, которая выводит подсчеты для каждого столбца, и мы надеемся выглядеть следующим образом:
Priority | SSM | Abortion | Climate |
High 2 2 1
Medium 1 0 1
Low 1 1 2
Относительно простой способ, который работает в любой базе данных, - использовать union all
:
select 'High' as priority,
sum(case when SSM = 'High' then 1 else 0 end) as SSM,
sum(case when Abortion = 'High' then 1 else 0 end) as Abortion,
sum(case when Climate = 'High' then 1 else 0 end) as climate
from t
union all
select 'Medium' as priority,
sum(case when SSM = 'Medium' then 1 else 0 end) as SSM,
sum(case when Abortion = 'Medium' then 1 else 0 end) as Abortion,
sum(case when Climate = 'Medium' then 1 else 0 end) as climate
from t
union all
select 'Low' as priority,
sum(case when SSM = 'Low' then 1 else 0 end) as SSM,
sum(case when Abortion = 'Low' then 1 else 0 end) as Abortion,
sum(case when Climate = 'Low' then 1 else 0 end) as climate
from t;
В большинстве баз данных вы можете объединить это:
select p.priority,
sum(case when t.SSM = p.priority then 1 else 0 end) as SSM,
sum(case when t.Abortion = p.priority then 1 else 0 end) as Abortion,
sum(case when t.Climate = p.priority then 1 else 0 end) as climate
from (select 'High' as priority, 1 as ord union all
select 'Medium' as priority, 2 as ord union all
select 'Low' as priority, 3 as ord
) p cross join
t
group by p.priority, p.ord
order by p.ord;
Я принял ответ @Gordon Linoffs, потому что это ответ на вопрос. Но Клубника заставила меня подумать, что я неправильно сформулировал проблему. Мне нужно было преобразовать широкий набор данных в длинный, а затем сделать подсчет. Я получил это от использования PIVOT для Flip Data от Wide to Tall
Чтобы сделать это для моего примера:
SELECT t.condition, t.prioirty, count(t.priority)
FROM(
SELECT "Abortion" as condition, df.abortion
FROM df
WHERE df.abortion!=""
UNION ALL
SELECT "SSM" as condition, df.SSM
FROM df
WHERE df.SSM!=""
UNION ALL
SELECT "Climate" as condition, df.climate
FROM df
WHERE df.climate!="" ) as t
GROUP BY t.condition, t.priority
Может быть, есть более простой способ сделать это, но data.world не поддерживает CROSS APPLY