Суммируя 4 псевдонима

У меня есть следующий запрос:

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

Я хочу иметь еще один столбец под названием «всего», в котором есть сумма всех четырех псевдонимов.

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
0
107
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

В MySQL 5.7+, MySQL 8.0+ этот запрос не будет работать.

Nick 04.03.2019 02:32

Вы не можете повторно использовать псевдонимы. Самый простой способ написать код использует 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» — ложно. Это удобно, когда вы хотите подсчитать количество истинных значений некоторого выражения.

Другие вопросы по теме