Aliases de subconsultas iguais aos aliases de consultas principais


23

Eu tenho uma consulta SQL cujos aliases são os mesmos que alguns dos aliases de sua subconsulta.

Por exemplo:

select *
from ROOM r
where ...
         (
              select *
              from ROAD r
              where ...
         )

Isso funciona bem, pois o apelido da subconsulta parece ocultar o principal.

  1. Funcionará assim em todos os casos?
  2. Vou obter resultados indefinidos?
  3. Se não for possível fazer isso, como posso fazer uma referência às consultas principais r?

1
Respostas curtas são "1.Sim", "2.No" e "3.in Nesse caso, você não pode (por isso não é realmente OK, se você quiser fazer essa referência)"
ypercubeᵀᴹ

Respostas:


15

Não há problema em subconsultas aninhadas usarem os mesmos aliases usados ​​na consulta pai, embora possa ser um pouco confuso para alguém ler o código. O espaço de nome para aliases em uma subconsulta aninhada é separado do espaço de nome no pai. Por exemplo, a consulta abaixo tem uma subconsulta aninhada bque também possui um alias busado nela. Isso seria potencialmente confuso para o programador, mas adequado para o mecanismo DBMS:

   select a.foo
          ,b.bar
          ,b.BarCount
      from (select b.bar
                  ,count (*) as BarCount
              from BarTable b
              join OtherTable o
                on b.OtherTableID = o.OtherTableID
             group by b.bar) b
      join Foobar a
        on a.bar = b.bar

Em uma subconsulta correlacionada, você tem acesso aos aliases do pai, portanto, os aliases devem ser únicos na consulta pai e na subconsulta correlacionada. Se fizermos uma subconsulta correlacionada como a abaixo, teremos um único espaço de nome global compartilhado entre a consulta pai e a subconsulta correlacionada:

select a.foo
      ,b.bar
  from Foobar a
  join Bar b
    on b.FooBarID = a.FooBarID
 where not exists
       (select 1
          from Bar b2
         where b2.BarCategoryID = b.BarCategoryID
           and b2.BarDate > b.BarDate)

A subconsulta correlacionada não possui um alias, pois não participa de uma associação como tal 1 . As referências be b2for barestão disponíveis para a subconsulta, pois as subconsultas correlacionadas compartilham seu espaço de nomes para aliases com o pai.


1 Observe que o otimizador pode optar por usar operadores de junção dentro do plano nos bastidores, embora a operação real especificada seja uma subconsulta correlacionada e não uma junção contra uma subconsulta aninhada.


A subconsulta na primeira consulta é uma tabela derivada e o SQL padrão exige que sempre seja dado um nome: não há motivo lógico para esse requisito, mas o SQL Server o implementou de qualquer maneira, embora no exemplo específico que você escolheu um nome seja realmente requeridos. A subconsulta na segunda consulta não é uma tabela derivada, portanto, por que ela não requer um nome (o fato de ser uma subconsulta correlacionada é irrelevante).
usar o seguinte código

@ onedaywhen - Não consigo pensar em nenhuma situação além de uma subconsulta correlacionada em que a subconsulta precisa acessar os aliases usados ​​no pai. Você tinha algo específico em mente?
ConcernedOfTunbridgeWells

Não sei se entendi sua pergunta. Talvez eu deva deixar claro que estava respondendo especificamente ao seu comentário: "A subconsulta correlacionada não possui um alias, pois não participa de uma associação como tal". Minha resposta deveria transmitir o argumento de que as regras relativas às variáveis ​​de intervalo (o que o padrão SQL chama de 'nomes de correlação' e você chama de 'aliases') não estão diretamente relacionadas à sua participação (ou não) nas junções.
usar o seguinte código

Exemplo simples: SELECT * FROM ( SELECT c FROM T ) AS T2;- sem junções, sem correlação, ainda que o padrão SQL exija que a tabela derivada receba uma variável de intervalo ( T2neste caso).
usar o seguinte código

3

ConcernedOfTunbridgeWells, você escreve (ênfase minha): "Em uma subconsulta correlacionada, você tem acesso aos aliases dos pais, portanto os aliases devem ser exclusivos na consulta pai e na subconsulta correlacionada."

Eu não acredito que a exclusividade seja necessária. Acredito que, se um alias for usado em uma subconsulta correlacionada como um nome de correlação, bem como um alias de tabela na consulta externa, o alias na subconsulta terá precedência.

Exemplo:

CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)

INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)

SELECT
    T1.A
FROM
    #T AS T1
    INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
    EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)

A saída é "3": as tabelas T e U têm 2 e 3 em comum, mas o WHEREpredicado filtra ainda mais as linhas retornadas a 3 e 2 não existe em V.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.