Подтвердить что ты не робот

SQL Server - используйте столбцы из основного запроса в подзапросе

Есть ли способ получить столбец в реальном времени, из основного запроса и использовать его в подзапросе?

Что-то вроде этого: (Использовать A.item в подзапросе)

SELECT item1, * 
FROM TableA A 
INNER JOIN 
(
    select * 
    from TableB B 
    where A.item = B.item
) on A.x = B.x;

Хорошо, вот настоящая вещь:

Мне нужно изменить этот существующий запрос. Он работал до этого, но теперь, когда база данных изменилась, мне нужно внести некоторые изменения, добавить некоторые сравнения. Как вы можете видеть, существует много JOINS, и один из них является подзапросом. Мне нужно добавить сравнение из столбца из основного запроса (например, из таблицы T0) в подзапрос (например: T6.UnionAll_Empresa = T0.UnionALl_Empresa)

Select T0.UnionAll_Empresa,<STUFF>

from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join

(
select 
t1.CompanyID,
T2.CompanyDb,
t1.OurNumber,
T6.BankCode,
T6.BankName,
T3.[Description] Situation,
T1.[Status],
T5.Descrption nomeStatus,
T1.Origin,
T1.DocEntry,
T1.DocType,
T1.ControlKey,
T1.CardCode,
T4.[Description] ContractBank,
T1.PayMethodCode,
T1.DueDate,
T1.DocDate,
T1.InstallmentID,
T1.InstallmentValue,
T1.Correction,
T1.InterestContractural,
T1.FineContract,
T1.ValueAbatment,
T1.ValueDiscount,
T1.ValueFineLate,
T1.ValueInterestDaysOfLate,
T1.OtherIncreases,
T1.ValueInWords,
T1.ValueDocument,
T1.DigitalLine,
T1.Document
from [IntegrationBank]..BillOfExchange T1 with (nolock)
    inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
    left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID 
    inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID 
    inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID 
    inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and **T6.UnionAll_Empresa = T0.UnionALl_Empresa** --I need to do this 
where T1.[Status] <> 5 
and T2.CompanyDb = **T0.UnionAll_Empresa** --I need to do this
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType )
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (select 1
        from [UNION_ALL_BASES]..RIN1 A with (nolock) 
                inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
        where A.BaseEntry = T0.DocEntry
        and   B.SeqCode = ''1'' )
4b9b3361

Ответ 1

Пользователь может использовать OUTER APPLY

   SELECT  *
    FROM    tbl1
            OUTER APPLY ( SELECT TOP 1
                                    currency_id,
                                    SUM(taxrate) AS taxrate
                          FROM      tbl2
                          WHERE     wuptr.currency_id = tbl1.currency_id
                          GROUP BY  tbl2.currencyid
                        ) 

Ответ 2

Для этого вам не нужен подзапрос:

SELECT item1, * 
FROM TableA A 
INNER JOIN 
   TableB B 
     ON A.item = B.item
     AND A.x = B.x;

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

Вы можете ссылаться на внешнюю таблицу в подзапросе в предложении WHERE, хотя:

SELECT <stuff>
FROM Table t
WHERE EXISTS  (SELECT 1 from TableB B 
               WHERE t.id = b.id)

ИЗМЕНИТЬ

Для вашего фактического кода просто измените критерии JOIN на это:

) TBI on (T1.DocEntry = TBI.DocEntry
          and T1.InstlmntID = TBI.InstallmentID 
          and TBI.DocType = T1.ObjType
          AND TBI.CompanyDB = T0.UnionAll_Empresa )

Ответ 3

Если вы хотите присоединиться к подзапросу и получить столбец в режиме реального времени/ссылаться на столбец из основного запроса, то есть трюк для этого.

Вы не можете получить доступ к таблицам, которые находятся за пределами подзапроса, если он используется как таблица с псевдонимом, другими словами, этот SQL никогда не сможет получить доступ к A:

...
INNER JOIN 
(
    select * 
    from TableB B 
    where A.item = B.item
) on A.x = B.x;

Способ доступа к A будет таким:

SELECT item1, * 
FROM TableA A 
INNER JOIN TableB on TableB.item = TableA.item and TableB.item in
(
    select top 1 B.Item
    from TableB B 
    where A.item = B.item
)

Просто проигнорируйте часть "top 1", я просто добавил, что показать, что может быть причина для такого объединения.
Итак, в основном, если вы хотите ссылаться на элемент из запроса в подзапросе, просто переместите подзапрос в раздел "Включение" соединения и используйте ключевое слово IN, как показано выше.

Ответ 4

Вы можете сделать это, назвав таблицы основного запроса и вложенный запрос. Например:

SELECT continent, name, population FROM world x
  WHERE population >= ALL
    (SELECT population FROM world y
        WHERE y.continent=x.continent
          AND population>0)

ссылка: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial

Ответ 5

Не уверен, почему люди слишком усложняют это. @JNK правильно, что вы можете перенести предикат в основной запрос. Для полноты я продемонстрирую.

В вашем подзапросе есть два предиката: reference T0:

T6.UnionAll_Empresa = T0.UnionAll_Empresa
T2.CompanyDb = T0.UnionAll_Empresa

Первым является предикат INNER JOIN в таблице T6, а второй a WHERE - эти оба являются "жесткими" фильтрами и будут отфильтровывать результаты, которые не совпадают (в отличие от LEFT OUTER JOIN, который просто установит ссылку на эти значения таблицы на NULL).

Ну, так как T6.UnionAll_Empresa и T2.CompanyDb оба должны фильтроваться против T0.UnionAll_Empresa, тогда мы можем просто изменить предикат INNER JOIN на T6 на следующее:

T2.CompanyDb = T6.UnionAll_Empresa

Затем мы можем удалить предложение WHERE в подзапросе, и мы можем добавить этот предикат JOIN в TBI в основной запрос:

TBI.CompanyDb = T0.UnionAll_Empresa

... делая весь запрос следующим:

Select T0.UnionAll_Empresa,<STUFF>

from [UNION_ALL_BASES]..OINV T0 with (nolock)
inner join [UNION_ALL_BASES]..INV6 T1 with (nolock) on t0.DocEntry = t1.DocEntry and t0.UnionAll_Empresa = t1.UnionAll_Empresa
inner join
(
    select 
    t1.CompanyID,
    T2.CompanyDb,
    t1.OurNumber,
    T6.BankCode,
    T6.BankName,
    T3.[Description] Situation,
    T1.[Status],
    T5.Descrption nomeStatus,
    T1.Origin,
    T1.DocEntry,
    T1.DocType,
    T1.ControlKey,
    T1.CardCode,
    T4.[Description] ContractBank,
    T1.PayMethodCode,
    T1.DueDate,
    T1.DocDate,
    T1.InstallmentID,
    T1.InstallmentValue,
    T1.Correction,
    T1.InterestContractural,
    T1.FineContract,
    T1.ValueAbatment,
    T1.ValueDiscount,
    T1.ValueFineLate,
    T1.ValueInterestDaysOfLate,
    T1.OtherIncreases,
    T1.ValueInWords,
    T1.ValueDocument,
    T1.DigitalLine,
    T1.Document
    from [IntegrationBank]..BillOfExchange T1 with (nolock)
    inner join [InterCompany2]..CompanyHierarchy T2 with (nolock) on T1.CompanyID = T2.ID
    left join [IntegrationBank]..BillOfExchangeSituation T3 with (nolock) on T1.Situation = T3.ID 
    inner join [IntegrationBank]..ContractBank T4 with (nolock) on T1.ContractBank = T4.ID 
    inner join [IntegrationBank]..BoeStatus T5 with (nolock) on T1.[Status] = T5.ID 
    inner join [UNION_ALL_BASES]..ODSC T6 with (nolock) on T4.BankKey = T6.AbsEntry and T2.CompanyDb = T6.UnionAll_Empresa
    where T1.[Status] <> 5 
) TBI on (T1.DocEntry = TBI.DocEntry and T1.InstlmntID = TBI.InstallmentID and TBI.DocType = T1.ObjType and TBI.CompanyDb = T0.UnionAll_Empresa)
inner join [UNION_ALL_BASES]..OCTG T2 on T0.GroupNum = T2.GroupNum and T0.UnionAll_Empresa = T2.UnionAll_Empresa
inner join [UNION_ALL_BASES]..OSLP T3 on T0.SlpCode = T3.SlpCode and T0.UnionAll_Empresa = T3.UnionAll_Empresa
where not exists (
    select 1
    from [UNION_ALL_BASES]..RIN1 A with (nolock) 
    inner join [UNION_ALL_BASES]..ORIN B with (nolock) on A.DocEntry = B.DocEntry and A.UnionAll_Empresa = B.UnionAll_Empresa
    where A.BaseEntry = T0.DocEntry
    and B.SeqCode = ''1''
)

Это полностью эквивалентно тому, что у вас есть, и удаляет любую ссылку на T0 из вашего подзапроса.