sql группировка с условиями

116
30 марта 2022, 00:10

http://sqlfiddle.com/#!9/aef5ce/7

В примере выполняются 2 запроса к таблице. Запросы одинаковые, разница только в значении format_id в условии.

В первом ищем format_id = 999 (которого нет в таблице) или NULL, во втором ищем format = 1 (который есть в таблице) или NULL.

Каким образом можно преобразовать эти запросы так, чтобы если мы задаем существующий format_id в таблицах, возвращались только строки с ним (NULL игнорировался). А если такой не существует, то соответственно тянулись те данные, в которых format_id = NULL.

В общем хочется чтобы при заданном format_id = 1 вернулось (3 строки, вместо 6 строк)

100 1 20
200 1 40
300 1 60

При заданном format_id = 999 (или любое другое несуществующее значение) вернулся тот результат, который сейчас отображается в примере в результате 1-го запроса (то есть значение для строки с format_id = null).

Answer 1
SELECT circulation, format_id, min(price1)
FROM table1
WHERE section_id = 1 
  AND CASE WHEN  0 = ( SELECT COUNT(*) 
                       FROM table1
                       WHERE format_id = @format_id )
           THEN format_id IS NULL
           ELSE format_id = @format_id
           END
GROUP BY circulation, format_id
order by circulation ASC, format_id DESC;

fiddle

Подобный подзапрос внутри не будет ли вызывать излишнюю загрузку? Собственно в этом и была вся проблема. Был в поисках адекватного решения, которое минимизирует нагрузку. Поэтому думал, что можно такое как-то провернуть с помощью 1 запроса. Но видимо нельзя?

На 5.6-то? Ну разве что вот так:

SELECT circulation, format_id, min(price1)
FROM table1, ( SELECT COUNT(*) cnt
               FROM table1
               WHERE format_id = @format_id ) sq
WHERE section_id = 1 
  AND CASE WHEN  sq.cnt
           THEN format_id = @format_id
           ELSE format_id IS NULL
           END
GROUP BY circulation, format_id
order by circulation ASC, format_id DESC;

fiddle

Хотя вряд ли будет какая разница...

А без подзапроса - ну никак.

Answer 2
SELECT circulation,
       max(format_id) format_id,
       coalesce( min( if(format_id is not null, price1, null) ), min(price1) ) price1
FROM table1
WHERE section_id = 1 AND (format_id = 2 OR format_id IS NULL)
GROUP BY circulation, format_id
order by circulation ASC;

Тест на sqlfiddle.com

READ ALSO
Intellij IDEA и java компилятор

Intellij IDEA и java компилятор

Получается, когда мы работаем в IDEA, то компилятор, будем говорить, отрабатывает еще в процессе написания кода, так? А когда мы запускаем код,...

158
В XML файле не прописывается путь к классу

В XML файле не прописывается путь к классу

При прописке в XML пути для бина выдает ошибку cannot resolve class or packageДа и при создании конструктора тоже ругается

92