Я хочу получить только 1 совпадение из моего ВНУТРЕННЕГО запроса на СОЕДИНЕНИЕ

#sql #oracle

Вопрос:

Я создаю таблицу, используя несколько внутренних запросов на объединение в других таблицах, и один из моих запросов возвращает несколько совпадений (правильно в зависимости от того, как работает эта функция), но мне действительно просто нужно вернуть одно совпадение, первое, которое оно попадет в сравнение, подойдет. Ниже приведен мой код. В последнем запросе ВНУТРЕННЕГО СОЕДИНЕНИЯ может быть несколько совпадений.transaction_id = e.pb_trans_id в таблице repldoadm.vw_ire_trade_transactions e. Могу ли я указать, чтобы просто вернуть 1 совпадение?

»’

     SELECT

    distinct a.transaction_id,
    b.currency_id,
    h.SIG_CURRENCY_CODE,
    b.charge_id,
    c.charge_type_id,
    d.charge_group,
    e.account_name,
    f.sig_entity_label,
    e.trading_userid,
    e.exchange_id,
    e.tradeable_instr_name,
    g.underlying_sym_bloomberg,
    g.fut_expiration_date,
    e.trade_date,
    timestamp_table.timeformated,
    a.rate * a.basis_value AS dma_fee,
    SUM(A.RATE * A.BASIS_VALUE) OVER () as DMA_FEE_TOTAL
FROM
    repldoadm.ire_estimate_trans_map       a
    LEFT JOIN repldoadm.ire_charges_estimate         b ON a.estimate_id = b.estimate_id
    LEFT JOIN repldoadm.ire_charges_lu               c ON b.charge_id = c.charge_id
    LEFT JOIN repldoadm.ire_charge_types_lu          d ON c.charge_type_id = d.charge_type_id
    LEFT JOIN repldoadm.vw_ire_trade_transactions    e ON a.transaction_id = e.pb_trans_id --or a.transaction_id = e.PB_TRANS_ID
    LEFT JOIN (
        SELECT
            to_char(create_ts, 'HH24:MI:SS') AS timeformated,
            trans_id,
            pb_trans_id
        FROM
            repldoadm.vw_ire_trade_transactions
    )                                      timestamp_table ON ( a.transaction_id = timestamp_table.trans_id or a.transaction_id = timestamp_table.pb_trans_id)
    LEFT JOIN repldoadm.vw_ire_accounts              f ON e.account_name = f.pb_account_name
    LEFT JOIN stig_adm.instrument_universe           g ON e.tradeable_instr_name = g.short_name
    LEFT JOIN STIG_ADM.BBG_LU_CURRENCY h                ON c.payment_currency_id = h.SIG_CURRENCY_ID
 

»’

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

1. «…но мне действительно просто нужно отодвинуть одну спичку…» — Как вы решаете, какую из них выбрать? Просто случайный, с наибольшей ценностью чего-то и т. Д…

2. INNER JOIN В вашем запросе нет, поэтому ваш вопрос не имеет смысла.

3. @TheImpaler да, случайность-это нормально

4. @GordonLinoff я имел в виду левое присоединение

Ответ №1:

Для этого вы можете использовать боковое соединение с предельным предложением. Для бокового внешнего соединения я предлагаю использовать OUTER APPLY , потому что, в отличие от с LEFT JOIN LATERAL , вам не нужно добавлять фиктивное ON предложение, чтобы сделать это синтаксически правильным.

 SELECT
    distinct a.transaction_id,
    b.currency_id,
    h.SIG_CURRENCY_CODE,
    b.charge_id,
    c.charge_type_id,
    d.charge_group,
    e.account_name,
    f.sig_entity_label,
    e.trading_userid,
    e.exchange_id,
    e.tradeable_instr_name,
    to_char(e.create_ts, 'HH24:MI:SS'),
    g.underlying_sym_bloomberg,
    g.fut_expiration_date,
    e.trade_date,
--    timestamp_table.timeformated,
    a.rate * a.basis_value AS dma_fee,
    SUM(A.RATE * A.BASIS_VALUE) OVER () as DMA_FEE_TOTAL
FROM
    repldoadm.ire_estimate_trans_map       a
    LEFT JOIN repldoadm.ire_charges_estimate         b ON a.estimate_id = b.estimate_id
    LEFT JOIN repldoadm.ire_charges_lu               c ON b.charge_id = c.charge_id
    LEFT JOIN repldoadm.ire_charge_types_lu          d ON c.charge_type_id = d.charge_type_id
    OUTER APPLY
    (
      SELECT *
      FROM repldoadm.vw_ire_trade_transactions tt
      WHERE tt.pb_trans_id = a.transaction_id
      FETCH FIRST ROW ONLY
    ) e;
 

Ответ №2:

Если вам все равно, какую строку возвращать, возможно, ROW_NUMBER вам поможет аналитическая функция. Ваш текущий запрос — с добавлением именованной функции — будет использоваться в качестве подзапроса (или CTE, как в моем примере), в то время как «окончательный» запрос вернет строки, которые RN = 1 .

Что-то вроде этого:

 WITH temp AS
      (  SELECT DISTINCT a.transaction_id,
                b.currency_id,
                h.SIG_CURRENCY_CODE,
                b.charge_id,
                c.charge_type_id,
                d.charge_group,
                e.account_name,
                f.sig_entity_label,
                e.trading_userid,
                e.exchange_id,
                e.tradeable_instr_name,
                TO_CHAR (e.create_ts, 'HH24:MI:SS'),
                g.underlying_sym_bloomberg,
                g.fut_expiration_date,
                e.trade_date,
                a.rate * a.basis_value AS dma_fee,
                SUM (A.RATE * A.BASIS_VALUE) OVER () AS DMA_FEE_TOTAL,
       -- this:
                ROW_NUMBER () OVER (PARTITION BY e.pb_trans_id ORDER BY e.create_ts DESC) rn
           FROM repldoadm.ire_estimate_trans_map a
                LEFT JOIN repldoadm.ire_charges_estimate b
                   ON a.estimate_id = b.estimate_id
                LEFT JOIN repldoadm.ire_charges_lu c
                   ON b.charge_id = c.charge_id
                LEFT JOIN repldoadm.ire_charge_types_lu d
                   ON c.charge_type_id = d.charge_type_id
                LEFT JOIN repldoadm.vw_ire_trade_transactions e
                   ON a.transaction_id = e.pb_trans_id
      )
SELECT t.*
  FROM temp t
 WHERE t.rn = 1
 

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

1. Вы ошибаетесь. Здесь не должно быть никаких GROUP BY оговорок. Я полагаю, вы следили за пунктом О ПРЕВЫШЕНИИ СУММЫ.

2. Упс! Аналитическая форма функции СУММЫ! Я следил за этим, я ошибся, меня предупредили, я все исправил. Спасибо тебе, @Торстен!

3. @Littlefoot спасибо за это. Поразмыслив, я бы на самом деле хотел отфильтровать запись, которую я возвращаю, по критерию. Я также обновил код в своем первоначальном фрагменте, чтобы предоставить то, что я использую сейчас. У меня есть новый оператор СОЕДИНЕНИЯ СЛЕВА, чтобы ввести поле времени, и это на самом деле то, что заставляет меня вводить несколько записей, когда я хочу только одну (только для этого соединения). Как бы я отфильтровал этот оператор соединения, чтобы он возвращал запись с последней отметкой времени в этом поле?