As subconsultas adicionam poder expressivo às consultas SQL?


29

O SQL precisa de subconsultas?

Imagine uma implementação suficientemente generalizada da linguagem de consulta estruturada para bancos de dados de relações. Como a estrutura da SELECTinstrução SQL canônica é realmente muito importante para que isso faça sentido, não apelo diretamente à álgebra relacional, mas você pode enquadrar isso nesses termos, fazendo restrições apropriadas na forma das expressões.

Um SQL SELECTconsulta geralmente consiste de uma projecção (a SELECTparte) um certo número de JOINoperações (a JOINparte), um certo número de SELECTION operações (em SQL, as WHEREcláusulas), e, em seguida, definir-sábio operações ( UNION, EXCEPT, INTERSECT, etc), seguida por outra SELECTConsulta SQL .

As tabelas que estão sendo unidas podem ser os resultados calculados das expressões; em outras palavras, podemos ter uma declaração como:

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) AS t2
 WHERE t1.salary > 50,000;

Vamos nos referir ao uso de uma tabela computada como parte de uma consulta SQL como uma subconsulta. No exemplo acima, o segundo (recuado) SELECTé uma subconsulta.

Todas as consultas SQL podem ser gravadas de maneira a não usar subconsultas? O exemplo acima pode:

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN table2 AS t2
    ON t1.id = t2.id
 WHERE t1.salary > 50,000;

Este exemplo é um tanto espúrio ou trivial, mas pode-se imaginar casos em que um esforço consideravelmente maior pode ser necessário para recuperar uma expressão equivalente. Em outras palavras, é o caso de cada consulta SQL com subconsultas, existe uma consulta q ' sem subconsultas, de forma que e são garantidos para produzir os mesmos resultados para as mesmas tabelas subjacentes? Vamos limitar as consultas SQL ao seguinte formato:qqqq

SELECT <attribute>,
      ...,
      <attribute>
 FROM <a table, not a subquery>
 JOIN <a table, not a subquery>
  ...
 JOIN <a table, not a subquery>
WHERE <condition>
  AND <condition>
  ...
  AND <condition>

UNION
 -or-
EXCEPT
 -or-
<similar>

SELECT ...

E assim por diante. Acho que as junções externas esquerda e direita não acrescentam muito, mas se eu estiver enganado, sinta-se à vontade para apontar isso ... de qualquer forma, elas também são um jogo justo. No que diz respeito às operações definidas, acho que qualquer uma delas é boa ... união, diferença, diferença simétrica, interseção, etc ... qualquer coisa que seja útil. Existem formulários conhecidos nos quais todas as consultas SQL podem ser reduzidas? Algum deles elimina subconsultas? Ou existem alguns casos em que não existe consulta equivalente livre de subconsulta? As referências são apreciadas ... ou uma demonstração (por prova) de que são ou não são necessárias seria fantástica. Obrigado e desculpe se este é um resultado célebre (ou trivial) do qual sou dolorosamente ignorante.


5
Meu instinto me diz que você sempre pode juntar tudo e selecionar a partir daí, desde que não precise de valores agregados. A seleção de todas as entradas com um valor maior que a média de sua coluna parece exigir o cálculo da média primeiro, necessitando, portanto, de uma subconsulta.
Raphael

@ Rafael, eu tenho certeza que você pode até mesmo fazer valores agregados, você só precisa fazer mais auto-junções e agrupamentos (tornando-os exponencialmente maiores, mas ainda possíveis). Não tenho certeza de como eu formalmente provaria que você pode fazer tudo dessa maneira.
Kevin

@ Kevin Você tem certeza de que o número de operações necessárias não depende do número de linhas? Porque não podemos ter isso, podemos?
Raphael

1
O exemplo normal, eu tenho para exigir uma subconsulta está contando duplicatas: select count(*) from (select id from sometable group by id having count(*)>1) d. Porque inclui group by, não coloquei isso como resposta.
Mark Hurd

BTW AFAIK no SQL normal, a ONcláusula é necessária para JOINs, embora um produto cruzado seja obtido com apenas uma vírgula.
Mark Hurd

Respostas:


9

Há alguma confusão terminológica; o bloco de consulta entre parênteses

SELECT t1.name, t2.address
  FROM table1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) 

é chamado de visão interna . Uma subconsulta é um bloco de consulta na cláusula WHERE ou SELECT, por exemplo

select deptno from dept
where 3 < (select count(1) from emp 
           where dept.deptno=emp.deptno)

Em ambos os casos, a visualização interna ou a subconsulta podem ser aninhadas na junção restrita do projeto "simples". Subconsulta correlacionada com agregação desagraia em visualizações internas com agrupamento, que desassocia em consulta simples.

select deptno from dept d
    where 3 < (select avg(sal) from emp e
               where d.deptno=e.deptno)

select d.deptno from dept d, ( 
    select deptno from emp e
    group by deptno
    having avg(sal) > 3
) where d.deptno=e.deptno

select d.deptno from dept d, emp e
where d.deptno=e.deptno 
group by d.deptno
having avg(sal) > 3

Quanto às regras algébricas para otimização de consultas, sabe-se que a álgebra relacional é axiomatizada no Relational Lattice, o que simplifica as transformações de consultas, como demonstrado aqui e ali .


Estou curioso. Você pode adicionar um exemplo de consulta que usa alguns campos da média, por exemplo, selecionando todas as entradas com valor acima da média? Não está claro para mim como isso seria depois do achatamento.
Raphael

16

Para traduzir sua afirmação na álgebra relacional, acho que ela pergunta:

σUMA(UMA)σB(B)σUMA(σB(UMAB))

σ

A resposta é "Sim" e é uma otimização de consulta padrão. Para ser sincero, não sei como provar isso de uma maneira que não implique perguntas - é apenas uma propriedade de seleção e associação. Você pode argumentar indutivamente para adicionar quantas camadas de consultas aninhadas desejar.

Além disso, você pode perguntar:

UMABC...(UMAB)(CD)

Novamente, a resposta é sim, porque a união é associativa. Declarações semelhantes também podem ser feitas sobre a projeção.

Um tipo notável de "subconsulta" que eu acho que não pode ser "achatado" é with. Uma maneira de ver isso é notar que, se você tiver uma withinstrução, poderá ter uma função recursiva, que não pode ser escrita sem o uso de subconsultas.

Para resumir: no caso específico que você mencionou, não, o SQL não precisa de subconsultas, e você pode provar isso de forma indutiva. Em geral, porém, existem recursos que requerem subconsultas.


O comportamento recursivo via withfoi introduzido no SQL: 1999 e torna a linguagem resultante estritamente mais expressiva.
András Salamon

1

"As subconsultas adicionam poder expressivo às consultas SQL?"

Eles fizeram, pelo menos antes da introdução do EXCEPT na linguagem SQL.

Antes da introdução do EXCEPT, não havia como expressar uma diferença relacional ou semidiferença no SQL sem recorrer a subconsultas.

Atualmente, todos os operadores primitivos "típicos" da álgebra relacional "the" podem ser expressos sem subconsultas:

NATURAL JOIN pode ser feito através de NATURAL JOIN, ou JOIN ON
UNION pode ser feito através de UNION
MINUS pode ser feito através de EXCEPTO
PROJETO / RENAME / EXTEND pode ser feito através de SELECT
RESTRICT pode ser feito através de ONDE
literais relacionais podem ser feitos através de VALORES
fechamentos transitivos. ser feito através de WITH recursivo

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.