У меня есть следующий запрос:
SELECT
SUM(case when s1 = 'fel' then 1 else 0 end) as s1_count,
SUM(case when s2 = 'fel' then 1 else 0 end) as s2_count,
SUM(case when s3 = 'fel' then 1 else 0 end) as s3_count,
SUM(case when s4 = 'fel' then 1 else 0 end) as s4_count
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01'
Что выводит:
s1_count s2_count s3_count s4_count
17 13 6 3
Я хочу иметь еще один столбец под названием «всего», в котором есть сумма всех четырех псевдонимов.






Поскольку вы не можете использовать псевдонимы столбцов в предложении SELECT, есть несколько других способов сделать это. Либо добавьте еще одну условную агрегацию в свой запрос:
SELECT
SUM(case when s1 = 'fel' then 1 else 0 end) as s1_count,
SUM(case when s2 = 'fel' then 1 else 0 end) as s2_count,
SUM(case when s3 = 'fel' then 1 else 0 end) as s3_count,
SUM(case when s4 = 'fel' then 1 else 0 end) as s4_count,
SUM(case when s1 = 'fel' or s2 = 'fel' or s3 = 'fel' or s4 = 'fel' then 1 else 0 end) as total
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01'
Обратите внимание, что это предполагает, что только одно из s1, s2, s3 или s4 будет равно fel для любой данной строки.
Более надежным методом является использование исходного запроса в качестве подзапроса:
SELECT *, s1_count+s2_count+s3_count+s4_count AS total
FROM (SELECT
SUM(case when s1 = 'fel' then 1 else 0 end) as s1_count,
SUM(case when s2 = 'fel' then 1 else 0 end) as s2_count,
SUM(case when s3 = 'fel' then 1 else 0 end) as s3_count,
SUM(case when s4 = 'fel' then 1 else 0 end) as s4_count
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01') a
Обратите внимание, что поскольку MySQL обрабатывает логическое выражение в числовом контексте либо как 1 (истина), либо как 0 (ложь), вы можете упростить эти запросы следующим образом:
SELECT
SUM(s1 = 'fel') as s1_count,
SUM(s2 = 'fel') as s2_count,
SUM(s3 = 'fel') as s3_count,
SUM(s4 = 'fel') as s4_count,
SUM((s1 = 'fel') + (s2 = 'fel') + (s3 = 'fel') + (s4 = 'fel')) as total
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01'
SELECT *, s1_count+s2_count+s3_count+s4_count AS total
FROM (SELECT
SUM(s1 = 'fel') as s1_count,
SUM(s2 = 'fel') as s2_count,
SUM(s3 = 'fel') as s3_count,
SUM(s4 = 'fel') as s4_count
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01') a
Это устраняет проблему, которую первый запрос требовал, чтобы только одно из s1, s2, s3 или s4 было равно fel для любой данной строки.
Можешь попробовать:
SELECT s1_count, s2_count, s3_count, s4_count,
SUM(s1_count + s2_count + s3_count + s4_count) as total_count
FROM
(
SELECT
SUM(case when s1 = 'fel' then 1 else 0 end) as s1_count,
SUM(case when s2 = 'fel' then 1 else 0 end) as s2_count,
SUM(case when s3 = 'fel' then 1 else 0 end) as s3_count,
SUM(case when s4 = 'fel' then 1 else 0 end) as s4_count
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01'
) q
Вы не можете повторно использовать псевдонимы. Самый простой способ написать код использует in:
SELECT SUM(case when s1 = 'fel' then 1 else 0 end) as s1_count,
SUM(case when s2 = 'fel' then 1 else 0 end) as s2_count,
SUM(case when s3 = 'fel' then 1 else 0 end) as s3_count,
SUM(case when s4 = 'fel' then 1 else 0 end) as s4_count,
SUM(case when 'fel' in (s1, s2, s3, s4 ) then 1 else 0 end) as total
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01';
На самом деле весь запрос можно упростить до:
SELECT SUM( s1 = 'fel' ) as s1_count,
SUM( s2 = 'fel' ) as s2_count,
SUM( s3 = 'fel' ) as s3_count,
SUM( s4 = 'fel' ) as s4_count,
SUM( 'fel' in (s1, s2, s3, s4 ) ) as total
FROM `arrest`
WHERE date BETWEEN '2018-12-01' AND '2019-03-01';
MySQL обрабатывает логические значения как числа в числовом контексте, где «1» соответствует истине, а «0» — ложно. Это удобно, когда вы хотите подсчитать количество истинных значений некоторого выражения.
В MySQL 5.7+, MySQL 8.0+ этот запрос не будет работать.