loading..
Русский    English
16:19
листать

Оператор CASE стр. 3

Рассмотрим еще несколько примеров.

Посчитать количество рейсов из Ростова в Москву, и количество рейсов, выполняемых в остальные города.

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

Консоль
Выполнить
  1. SELECT flag, COUNT(*) qty FROM
  2. (SELECT CASE WHEN town_to ='Moscow' THEN 'Moscow' ELSE 'Other' END flag
  3. FROM Trip
  4. WHERE town_from='Rostov'
  5. ) X
  6. GROUP BY flag;

flag    qty
Moscow  4
Other    2

Посчитать общее количество рейсов из Ростова и количество рейсов, пунктом назначения которых не является Москва.

В этой задаче тоже требуется выполнить агрегацию по двум выборкам, при этом одна из выборок является подмножеством второй. Поэтому здесь напрямую не подойдёт вычисляемый столбец, по которому можно выполнить группировку. Это годилось для решения предыдущей задачи, когда множество делилось на собственные непересекающиеся подмножества, по каждому из которых требовалось выполнить агрегацию.

Для решения данной задачи мы можем посчитать количество по всему множеству и использовать подзапрос для подсчета значений в подмножестве (второе обращение к таблице) или использовать CASE в сочетании с агрегатной функцией, чтобы избежать повторного чтения таблицы. Давайте посмотрим, как оценит оптимизатор эти варианты.

Использование подзапроса

Консоль
Выполнить
  1. SELECT COUNT(*) total,
  2. (SELECT COUNT(*) FROM Trip
  3. WHERE town_from='Rostov' AND town_to <> 'Moscow') non_moscow
  4. FROM Trip
  5. WHERE town_from='Rostov';

 Использование CASE с агрегатной функцией

Консоль
Выполнить
  1. SELECT COUNT(*) total_qty,  
  2. SUM(CASE WHEN town_to <>'Moscow' THEN 1 ELSE 0 END) non_moscow
  3. FROM Trip
  4. WHERE town_from='Rostov';

Результат, естественно, будет одинаков:

total   non_moscow
6    2


а вот стоимость второго запроса, как и ожидалось, оказалась вдвое ниже.

Вы можете сравнить реальное время выполнения, если сгенерируете достаточный объём данных.

Второй вариант можно записать более компактно, если использовать функцию NULLIF - сокращенный вариант частного случая использования CASE:

Консоль
Выполнить
  1. SELECT COUNT(*) total_qty,  
  2. COUNT(NULLIF(town_to, 'Moscow')) non_moscow
  3. FROM Trip
  4. WHERE town_from='Rostov';

Функция NULLIF возвращает NULL, если её аргументы равны, или первый аргумент в противном случае.

В решении используется тот факт, что агрегатные функции не учитывают NULL-значения,  которые появляются в аргументе функции COUNT тогда, когда город прибытия равен 'Moscow'.

Bookmark and Share
Страницы: 1 2 3 4
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INFORMATION_SCHEMA INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker Больше тэгов
Учебник обновлялся
месяц назад
https://exchangesumo.com/obmen/ECOPAYZRUB-TRX/
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.
Rambler's Top100