Количество строк подзапроса оператора CASE, которое будет использоваться в качестве результата

#sql #postgresql #count #subquery #case

#sql #postgresql #количество #подзапрос #регистр

Вопрос:

На данный момент у меня есть оператор CASE вида

 CASE    
        WHEN exists (SELECT * FROM subtable WHERE subtable.column1value = 's100')   
        THEN 'exists in column 1'    
        WHEN exists (SELECT * FROM subtable2 WHERE subtable2.column2value = 's100')    
        THEN 'exists in column 2'   
        ELSE ''   
END
  

Другими словами, у меня есть компоненты продукта контракта, которые могут существовать в разных местах, поэтому мне нужно выполнить поиск по этим таблицам и столбцам, и я хотел бы иметь по одному столбцу на контракт, который указывает, есть ли в этом контракте такие компоненты продукта вообще где-либо.

Теперь я хотел бы изменить это, чтобы отслеживать, сколько компонентов имеется в контракте, и сохранить это значение в результате, что-то вроде

 CASE    
        WHEN exists (SELECT COUNT(*) FROM subtable WHERE subtable.column1value = 's100')
        THEN COUNT(*)
        WHEN exists (SELECT COUNT(*) FROM subtable2 WHERE subtable2.column2value = 's100')
        THEN COUNT(*)
        ELSE 0
END
  

но это, очевидно, не работает. Есть ли какой-нибудь способ перефразировать это, чтобы у меня мог быть псевдоним для результата подсчета каждого подзапроса, или есть лучший подход в целом? Может быть, просто есть несколько подзапросов, в которых я выбираю количество результатов, а затем еще один столбец для суммы этих столбцов?

 (SELECT COUNT(*) FROM subtable WHERE subtable.column1value = 's100') AS result_column1,
(SELECT COUNT(*) FROM subtable2 WHERE subtable2.column2value = 's100') AS result_column2,
(result_column1   result_column2) AS sum_of_results

  

Это позволило бы выполнить работу, но звучит не очень красноречиво.

Ответ №1:

Вы могли бы использовать подзапрос:

 select result_column1, result_column2, result_column1   result_column2 sum_of_results
from (
    select
        (select count(*) from subtable  where subtable.column1value  = 100) as result_column1,
        (select count(*) from subtable2 where subtable2.column2value = 100) as result_column2
) x
  

Обратите внимание, что я удалил одинарные кавычки вокруг буквальных значений в where предложении; если эти столбцы числовые, их следует сравнивать как таковые.

Комментарии:

1. Мое плохое — «100» должно было быть упрощенным примером более длинного значения столбца varchar. Немного отредактировал мой исходный пост, чтобы выглядеть менее запутанным. 🙂

Ответ №2:

Если вы хотите, чтобы это было в одном столбце, просто сделайте:

 COALESCE(
  nullif((SELECT COUNT(*) FROM subtable WHERE subtable.column1value = '100'), 0),
  (SELECT COUNT(*) FROM subtable WHERE subtable.column1value = '100')
) 
  

Сначала null, если первый счетчик равен нулю (coalesce перейдет ко второму запросу), затем подсчитайте вторую таблицу — если записей нет, то в конце будет 0.

Ответ №3:

Поскольку вы используете регистр, я предполагаю, что вам нужно значение второго столбца только тогда, когда нет подтаблицы.column1value = ‘100’ запись

 select 
(CASE WHEN (SELECT true FROM subtable WHERE subtable.column1value = '100' limit 1) THEN (SELECT COUNT(*) FROM subtable WHERE subtable.column1value = '100')
      WHEN  (SELECT true FROM subtable2 WHERE subtable2.column2value = '100' limit 1) THEN (SELECT COUNT(*) FROM subtable2 WHERE subtable2.column2value = '100')
      ELSE 0 END) as column_name