2017-02-16 2 views
0

Может кто-нибудь объяснить, как выполняется этот запрос? Столбец credit_transaction_key не существует в financial_transaction, но он существует в financial_transaction_jnl. Я не понимаю, почему этот запрос выполняется даже в том случае, если столбец находится в одной таблице, но не в другой таблице. Разве это не просто ошибка?Оператор удаления SQL удаляет вместо ошибки

delete from financial_transaction_jnl 
where credit_transaction_key in 
     (select credit_transaction_key 
     from financial_transaction 
     where account_key in 
      (select account_key 
       from account 
       where created_by = (select USER_KEY 
            from USERS 
            where USER_ID = 'ME') 
       and created_dttm > Cast('2/16/2017' as datetime) 
      ) 
    ) 

financial_transaction: financial_transaction_key account_key

financial_transaction_jnl: financial_transaction_jnl_key financial_transaction_key credit_transaction_key

+0

Показать структуру таблицы для Financial_transaction. У меня проблемы с утверждением, которого он не существует. Но обратите внимание, что когеррированные подзапросы могут ссылаться на столбцы в пределах 1 уровня подзапроса. Поэтому, возможно, он возвращается к financial_transaction_jrnl и использует это значение как перекрестное соединение между financial_transaction_jrnl и financial_transaction. – xQbert

ответ

1

Столбец credit_transaction_key не существует в financial_transaction, но она существует в financial_transaction_jnl. [...] Не должна ли это просто ошибка?

Нет, если на самом деле financial_transaction не содержит столбец с именем credit_transaction_key затем в подзапросах, что идентификатор будет разрешен против списка столбцов набора внешнего ряда (то есть столбцы financial_transaction_jnl) для текущей строки. Так как значение, выбранное таким образом одно и то же значение, которое сравнивается против выбора, запрос вы представить имеет тот же эффект, как это несколько проще один:

delete from financial_transaction_jnl 
where exists (
    SELECT 1 
    from financial_transaction 
    where account_key in (
    select account_key 
    from account 
    where created_by = (SELECT USER_KEY FROM USERS WHERE USER_ID = 'ME') 
     AND created_dttm > Cast('2/16/2017' AS DATETIME) 
) 
) 

Поскольку раздел внешнего запроса WHERE поэтому оказывается не чтобы зависеть от значений в своей целевой таблице, либо все строки, либо ни одна из них не будут удалены. Это вряд ли будет желательным эффектом.

Квалификация имени столбца во внешнем запросе, как предлагает другой ответ, не изменит этого значения. Квалификация имени столбца в запросе внутри как financial_transaction.credit_transaction_key действительно вызовет ошибку запроса.

+0

Если это так, то это действительно глупо, как это работает. Но я соглашусь. – LetUsSeng

+0

@LetUsSeng, семантика явно застала вас врасплох, но они отнюдь не глупы. Обычно подзапрос должен ссылаться на значения из строки контекста его содержащего запроса; это даже имеет имя: a * коррелированный * подзапрос. Способ, который играет в вашем конкретном примере, бесполезен, но это хорошо известная, хорошо зарекомендовавшая себя и общая полезная функция языка. –

1

Вы должны использовать псевдонимы таблиц.

SQL должен предполагать, откуда идут ваши столбцы.

в этом случае все будет удален:

financial_transaction.redit_transaction_key in 
(SELECT credit_transaction_key from financial_transaction 

но вы, вероятно, пытается сделать это:

financial_transaction_jnl.redit_transaction_key in 
    (SELECT credit_transaction_key from financial_transaction 
Смежные вопросы