Внешнее соединение или динамический запрос, что лучше?

StackOverflow https://stackoverflow.com/questions/1291839

Вопрос

У меня есть следующие таблицы (я упростил данные, содержащиеся в таблицах).

RateTable
- rate_table_id [int]
- rate_table_name [nvarchar(50)]

RateTableUsed
- rate_used_id [int]
- rate_table_id [int] (key to RateTable.rate_table_id)
- customer_id [int] 

RateTableExtra
- rate_table_extra_id [int]
- rate_ extra_id [int] (key to RateExtra.rate_table_id)
- rate_used_id [int] (key to RateTableUsed.rate_used_id)

RateExtra
- rate_ extra_id [int]
- rate_extra_name [nvarchar(50)]


select rate_table_name, rate_table_extra_id, rate_extra_name from RateTableUsed rtu 
    innerjoin RateTable rt on rtu.rate_table_id = rt.rate_table_id 
    innerjoin RateTableExtra rte on rte.rate_table_id = rt.rate_table_id
    innerjoing RateExtr re on rte.rate_extra_id = re.rate_extra_id

RateExtra содержит только 3 значения с ключами 1, 2 и 3, а также названиями бензиновых сборов, платы за управление и GST.

Это отлично работает для своей текущей цели.Отображается список значений с совпадающими записями, а параметр RateExtra запрашивается только для имени_рейта_extra_name.

Итак, у меня могут быть следующие результаты:

  • Тариф1, 1, БензинДоплата
  • Таблица тарифов1, 2, Комиссия за управление
  • Тариф2, 3, БензинДоплата
  • Тарифная таблица4, 4, НДС
  • Тарифная таблица6, 5, БензинДоплата

Меня попросили изменить это так, чтобы каждая возвращаемая запись теперь включала записи для каждого значения в таблице RateExtra.Если соответствующих записей нет, данные из моей таблицы RateTableExtra должны вернуться как NULL.Итак, мои данные должны вернуться как:

  • Тариф1, 1, БензинДоплата
  • Таблица тарифов1, 2, Комиссия за управление
  • Таблица тарифов1, NULL, GST
  • Тариф2, 3, БензинДоплата
  • Таблица ставок2, NULL, плата за управление
  • Таблица тарифов2, NULL, GST
  • Таблица тарифов4, NULL, надбавка за бензин
  • Таблица ставок4, NULL, плата за управление
  • Тарифная таблица4, 4, НДС
  • Тарифная таблица6, 5, БензинДоплата
  • Таблица ставок6, NULL, плата за управление
  • Таблица тарифов6, NULL, GST

Я пробовал соединения OUTER, но они, похоже, не работают, я предполагаю, потому что данные RateExtra связаны с RateTableExtra, который вернет ноль.Сейчас я подумываю о создании динамического запроса, который будет получать мой исходный набор результатов, перебирать его, проверяя скорость_extra_id и, если его еще нет в наборе результатов, добавлять новую строку к результатам с данными NULL там, где мне это нужно.Я предполагаю, что это сработает, но у меня такое ощущение, что это будет убийственно для производительности.

Есть ли лучший способ сделать это?Надеюсь, кто-то может помочь, это будет очень признательно.

Это было полезно?

Решение

Попробуй это:

select 
    rate_table_name, 
    rate_table_extra_id, 
    rate_extra
from 
    RateTableUsed rtu
    inner join RateTable rt on
        rtu.rate_table_id = rt.rate_table_id
    cross join RateExtra re
    left outer join RateTableExtra rte on 
        rte.rate_table_id = rt.rate_table_id
        and rte.rate_extra_id = re.rate_extra_id
order by rt.rate_table_name, re.rate_extra_id

По сути, этот запрос представляет собой декартово соединение между RateTable и RateExtra, с left join чтобы найти значения RateTableExtra которые соответствуют этим парам.По сути, этот запрос возвращает все возможно комбинации RateTable и RateExtra, и покажем вам, какие из них есть у вас в RateTableExtra стол быстро.

Будьте осторожны с декартовыми соединениями.Они могут очень быстро выйти из-под контроля за столами разумного размера!Наслаждаться!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top