Выберите несколько запросов count в одном запросе


В настоящее время у меня есть 6 очень похожие запросы, которые я пытаюсь увеличить производительность, делая их все подзапросы в 1 запрос. Я не уверен, что это лучше с точки зрения производительности, сохраняя их 6 отдельных запросов, 1 запрос с подзапросами 6 (как показано ниже), или какой-либо другой метод, который мне не знаком.

SELECT 
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName) AS total,
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
  (SELECT COUNT(*) FROM table_one WHERE date=myDate AND name=myName AND CODE_C BETWEEN 100 AND 199) AS code_c_count
FROM table_one
WHERE ROWNUM=1


118
1
задан 26 января 2018 в 07:01 Источник Поделиться
Комментарии
2 ответа

Я предлагаю вам использовать обобщенное табличное выражение (Оракул называет это "вложенный запрос Факторинг"), по крайней мере, вы будете делать фильтрацию по дате и имени только один раз

WITH filter_by_date_name AS ( 
SELECT CODE_A, CODE_B, CODE_C FROM table_one WHERE date=myDate AND name=myName
)
SELECT
(SELECT COUNT(*) FROM filter_by_date_name) AS total,
(SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 100 AND 199) AS code_a_low_count,
(SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_A BETWEEN 200 AND 299) AS code_a_high_count,
(SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 100 AND 199) AS code_b_low_count,
(SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_B BETWEEN 200 AND 299) AS code_b_high_count,
(SELECT COUNT(*) FROM filter_by_date_name WHERE CODE_C BETWEEN 100 AND 199) AS code_c_count
FROM filter_by_date_name
WHERE ROWNUM=1

1
ответ дан 29 января 2018 в 10:01 Источник Поделиться

Это простая задача для условного агрегации с помощью случаях:

SELECT 
COUNT(*) AS total,
COUNT(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 END) AS code_a_low_count,
COUNT(CASE WHEN CODE_A BETWEEN 200 AND 299 THEN 1 END) AS code_a_high_count,
COUNT(CASE WHEN CODE_B BETWEEN 100 AND 199 THEN 1 END) AS code_b_low_count,
COUNT(CASE WHEN CODE_B BETWEEN 200 AND 299 THEN 1 END) AS code_b_high_count,
COUNT(CASE WHEN CODE_C BETWEEN 100 AND 199 THEN 1 END) AS code_c_count
FROM table_one
WHERE date=myDate AND name=myName

Как ты считаешь, можно вернуть все что угодно (кроме null) в то.

Это может также быть написано как сумма за 1/0:

SUM(CASE WHEN CODE_A BETWEEN 100 AND 199 THEN 1 ELSE 0 END)

1
ответ дан 29 января 2018 в 03:01 Источник Поделиться