2013-05-14 2 views
1

Представьте торговый стол и таблицу cds_coupon, соединенную с торговым идентификатором; таблица купона с датой расчета и расчетной суммой. Требуемый запрос заключается в том, чтобы получить сумму и дату следующего купона.Как ссылаться и повторно использовать сопроводительный запрос?

select t.tradeId AS tradeId, 
(
    select settlement_date from cds_coupon e 
    where t.tradeId=e.tradeId 
    and e.settlement_date = (select min(settlement_date) from cds_coupon ei where ei.tradeId = t.tradeId and ei.settlement_date > sysdate) 
) AS settlement_date, 
( 
    select settlement_amount from cds_coupon e 
    where t.tradeId=e.tradeId 
    and e.settlement_date = (select min(settlement_date) from cds_coupon ei where ei.tradeId = t.tradeId and ei.settlement_date > sysdate) 
) AS settlement_amount, 
    FROM Trade t 

Как можно видеть два уровня одинакового corelation делается дважды только, чтобы захватить другое поле - один раз, чтобы захватить дату расчетов и один раз, чтобы захватить суммы урегулирования. Отсюда вопрос - как ссылаться и повторно использовать сопроводительный запрос?

+0

Не можете ли вы преобразовать его в соединение с подзапросом? – Barmar

+0

В вашем запросе нет ничего, что требует присоединения к 'Trade'; Я предполагаю, что это упрощение фактического запроса. – Barmar

+0

Если вам нужны данные расчета для всех будущих купонов, следует использовать выражение 'AND' 'больше или равно' вместо 'равно', например. 'e.settlement_date> = (выберите min (sett_date)'? –

ответ

0

При использовании SQL Server вы можете использовать Common Table Expression (CTE).

;WITH SettlementDates() 
AS 
(
    SELECT tradeId, MIN(settlement_date) as settlement_date 
    FROM cds_coupon 
    WHERE settlement_date > sysdate 
    GROUP BY tradeId 
) 

SELECT e.trade_id, e.settlement_date, e.settlement_amount 
FROM cds_coupon e 
JOIN SettlementDates sd 
    ON (e.trade_id = sd.trade_id) 
    AND (e.settlement_date = sd.settlement_date) 
+0

Будет ли это работать с коррелированным подзапросом? – Barmar

+0

Thx. Это лучше, чем у меня, но купон все еще проверяется дважды, чтобы найти агрегированное значение (следующая дата расчета), а затем чтобы сравнить даты расчетов со следующей датой расчета, найденной для равенства, чтобы затем получить сумму расчета. –

0

Используйте JOIN вместо коррелированного подзапроса:

select t.tradeId, e.settlement_date, e.settlement_amount 
from Trade t 
join (select ei.tradeId, ei.settlement_date, ei.settlement_amount 
     from cds_coupon ei 
     join (select tradeId, min(settlement_date) min_date 
      from cds_coupon 
      where settlement_date > sysdate 
      group by tradeId) emin 
     on ei.tradeId = e.tradeId and ei.settlement_date = min_date) e 
on t.tradeId = e.tradeId 

Подзапрос является стандартной идиомы для нахождения строки, содержащей минимальное или максимальное значение поля.

+0

Thx. Это лучше, чем у меня, но купон все еще проверяется дважды один раз, чтобы найти агрегированное значение (следующая дата расчета), а затем сравнить даты расчетов на следующую дату расчета, найденную для равенства, чтобы затем получить сумму расчета. –

+0

Если у вас есть соответствующие индексы, второй должен быть просто просмотром индекса, а не сканированием таблицы. – Barmar

+0

Конечно, но обычно не было индекса в столбце агрегируются, а затем сравниваются с суммарным значением, например, датой определения в этом случае или говорят в другом аналогичный пример агрегирования и сопоставления таблицы продуктов и продаж, как find-sales-amount-near-to-the-average-sale и говорят о соответствующей дате продажи. –

Смежные вопросы