Как я должен написать этот SQL

#sql #relational-database #firebird

#sql #реляционная база данных #firebird

Вопрос:

Используя Firebird 3.0, у меня есть эти таблицы

введите описание изображения здесь

Таблица model_types имеет несколько типов, таких как Type1, type2, type3… и мне нужно получить результат, подобный этому:

 Type     All    UFZ   Tempered
=================================
Type1     45     23      12
Type2     0      0       0
Type3     2      0       0
  

Итак, я написал этот SQL:

 select 
    sum((window.win_width * window.win_height) / 144),
    model_types.model_type_description
from model_types
   left outer join models on (model_types.model_type_id = models.model_type_id)
   inner join series_model on (models.model_id = series_model.model_id)
   inner join window on (series_model.sm_id = window.sm_id)
 where (quote_id = 122) and (window.ufz = 0) and (window.tempered = 0)
 group by model_types.model_type_description
  

Проблема в том, что этот SQL выдает мне только «type1», если другие типы являются нулями, так как я перечисляю все типы из таблицы model_types, даже если они являются нулями?

Другой вопрос: в этом SQL условие where :

 (window.ufz = 0) and (window.tempered = 0)
  

представляет столбец «Все», в то время как для получения UFZ мне нужно использовать эти условия:

 (window.ufz = 1) and (window.tempered = 0)
  

и чтобы закалиться, мне нужно использовать эти условия:

 (window.ufz = 0) and (window.tempered = 1)
  

Итак, как я отображаю все 3 результата (все, UFZ, Tempered), каждый в отдельном столбце?

Ответ №1:

После многих тестов я обнаружил, что могу использовать Case , но не знаю, правильный ли мой SQL или нет, также он не отображает все типы моделей, если они являются нулями.

 select 
    sum(CASE WHEN (window.ufz = 0) and (window.tempered = 0)
      THEN ((window.win_width * window.win_height) / 144) END) AS models_all,

    sum(CASE WHEN (window.ufz = 1) and (window.tempered = 0)
      THEN ((window.win_width * window.win_height) / 144) END) AS models_ufz,

    sum(CASE WHEN (window.ufz = 0) and (window.tempered = 1)
      THEN ((window.win_width * window.win_height) / 144) END) AS models_temp,

    model_types.model_type_description
from model_types
   left outer join models on (model_types.model_type_id = models.model_type_id)
   inner join series_model on (models.model_id = series_model.model_id)
   inner join window on (series_model.sm_id = window.sm_id)
 where (quote_id = 122)
 group by model_types.model_type_description
  

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

1. Если вы хотите все , то вам не следует использовать ограничение типа (window.ufz = 0) and (window.tempered = 0) , потому что это ограничивается окнами, которые не являются ufz или temperated. Мне также интересно, хотите ли вы исключить окна с ufz и темперированием из ваших значений ‘models_ufz’ и ‘models_temp’. Возможно, вы захотите рассмотреть возможность публикации примеров данных для всех задействованных таблиц. Также обратите внимание, что left outer join в вашем запросе неявно преобразуется во внутреннее соединение с помощью window.ufz = ... и window.tempered = ... .

2. как избежать превращения внешнего соединения влево во внутреннее соединение? Я не использую window.ufz и window.tempered в предложении where.

Ответ №2:

Конструкция CASE имеет часть ELSE, где вы можете добавить значение по умолчанию для случая, когда ваша часть WHEN не проверена. Я думаю, что это дополнит недостающие данные результата вашего запроса.