Selecione (SQL) - Select (SQL)

A instrução SQL SELECT retorna um conjunto de registros de resultados de uma ou mais tabelas .

Uma instrução SELECT recupera zero ou mais linhas de uma ou mais tabelas de banco de dados ou visualizações de banco de dados . Na maioria dos aplicativos, SELECTé o comando de linguagem de manipulação de dados (DML) mais comumente usado . Como SQL é uma linguagem de programação declarativa , as SELECTconsultas especificam um conjunto de resultados, mas não especificam como calculá-lo. O banco de dados traduz a consulta em um " plano de consulta " que pode variar entre execuções, versões de banco de dados e software de banco de dados. Essa funcionalidade é chamada de " otimizador de consulta ", pois é responsável por encontrar o melhor plano de execução possível para a consulta, dentro das restrições aplicáveis.

A instrução SELECT tem muitas cláusulas opcionais:

  • SELECTcláusula é a lista de colunas ou expressões SQL que devem ser retornadas pela consulta. Esta é aproximadamente a operação de projeção da álgebra relacional .
  • ASopcionalmente, fornece um alias para cada coluna ou expressão na SELECTcláusula. Esta é a operação de renomeação de álgebra relacional .
  • FROM especifica de qual tabela obter os dados.
  • WHEREespecifica quais linhas recuperar. Esta é aproximadamente a operação de seleção de álgebra relacional .
  • GROUP BYagrupa linhas que compartilham uma propriedade para que uma função de agregação possa ser aplicada a cada grupo.
  • HAVING seleciona entre os grupos definidos pela cláusula GROUP BY.
  • ORDER BY especifica como ordenar as linhas retornadas.

Visão geral

SELECTé a operação mais comum em SQL, chamada de "consulta". SELECTrecupera dados de uma ou mais tabelas ou expressões. As SELECTinstruções padrão não têm efeitos persistentes no banco de dados. Algumas implementações não padrão de SELECTpodem ter efeitos persistentes, como a SELECT INTOsintaxe fornecida em alguns bancos de dados.

As consultas permitem que o usuário descreva os dados desejados, cabendo ao sistema de gerenciamento de banco de dados (DBMS) realizar o planejamento , a otimização e a execução das operações físicas necessárias para produzir aquele resultado conforme sua escolha.

Uma consulta inclui uma lista de colunas a serem incluídas no resultado final, normalmente imediatamente após a SELECTpalavra - chave. Um asterisco (" *") pode ser usado para especificar que a consulta deve retornar todas as colunas das tabelas consultadas. SELECTé a instrução mais complexa em SQL, com palavras-chave e cláusulas opcionais que incluem:

  • A FROMcláusula, que indica as tabelas das quais recuperar os dados. A FROMcláusula pode incluir JOINsubcláusulas opcionais para especificar as regras de junção de tabelas.
  • A WHEREcláusula inclui um predicado de comparação, que restringe as linhas retornadas pela consulta. A WHEREcláusula elimina todas as linhas do conjunto de resultados em que o predicado de comparação não é avaliado como True.
  • A GROUP BYcláusula projeta linhas com valores comuns em um conjunto menor de linhas. GROUP BYé freqüentemente usado em conjunto com funções de agregação SQL ou para eliminar linhas duplicadas de um conjunto de resultados. A WHEREcláusula é aplicada antes da GROUP BYcláusula.
  • A HAVINGcláusula inclui um predicado usado para filtrar as linhas resultantes da GROUP BYcláusula. Como atua sobre os resultados da GROUP BYcláusula, as funções de agregação podem ser usadas no HAVINGpredicado da cláusula.
  • A ORDER BYcláusula identifica quais colunas usar para classificar os dados resultantes e em qual direção classificá-los (crescente ou decrescente). Sem uma ORDER BYcláusula, a ordem das linhas retornadas por uma consulta SQL é indefinida.
  • A DISTINCTpalavra-chave elimina dados duplicados.

O exemplo a seguir de uma SELECTconsulta retorna uma lista de livros caros. A consulta recupera todas as linhas da tabela Book na qual a coluna de preço contém um valor maior que 100,00. O resultado é classificado em ordem crescente por título . O asterisco (*) na lista de seleção indica que todas as colunas da tabela Book devem ser incluídas no conjunto de resultados.

SELECT *
 FROM  Book
 WHERE price > 100.00
 ORDER BY title;

O exemplo a seguir demonstra uma consulta de várias tabelas, agrupamento e agregação, retornando uma lista de livros e o número de autores associados a cada livro.

SELECT Book.title AS Title,
       count(*) AS Authors
 FROM  Book
 JOIN  Book_author
   ON  Book.isbn = Book_author.isbn
 GROUP BY Book.title;

O resultado de exemplo pode ser semelhante ao seguinte:

Title                  Authors
---------------------- -------
SQL Examples and Guide 4
The Joy of SQL         1
An Introduction to SQL 2
Pitfalls of SQL        1

Sob a pré-condição de que isbn é o único nome de coluna comum das duas tabelas e que uma coluna chamada title existe apenas na tabela Book , pode-se reescrever a consulta acima da seguinte forma:

SELECT title,
       count(*) AS Authors
 FROM  Book
 NATURAL JOIN Book_author
 GROUP BY title;

No entanto, muitos fornecedores não oferecem suporte a essa abordagem ou exigem certas convenções de nomenclatura de coluna para que as junções naturais funcionem de maneira eficaz.

O SQL inclui operadores e funções para calcular valores em valores armazenados. O SQL permite o uso de expressões na lista de seleção para projetar dados, como no exemplo a seguir, que retorna uma lista de livros que custam mais de 100,00 com uma coluna sales_tax adicional contendo um valor de imposto sobre vendas calculado a 6% do preço .

SELECT isbn,
       title,
       price,
       price * 0.06 AS sales_tax
 FROM  Book
 WHERE price > 100.00
 ORDER BY title;

Subconsultas

As consultas podem ser aninhadas para que os resultados de uma consulta possam ser usados ​​em outra consulta por meio de um operador relacional ou função de agregação. Uma consulta aninhada também é conhecida como subconsulta . Enquanto as junções e outras operações de tabela fornecem alternativas computacionalmente superiores (isto é, mais rápidas) em muitos casos, o uso de subconsultas introduz uma hierarquia na execução que pode ser útil ou necessária. No exemplo a seguir, a função de agregação AVGrecebe como entrada o resultado de uma subconsulta:

SELECT isbn,
       title,
       price
 FROM  Book
 WHERE price < (SELECT AVG(price) FROM Book)
 ORDER BY title;

Uma subconsulta pode usar valores da consulta externa e, nesse caso, é conhecida como subconsulta correlacionada .

Desde 1999, o padrão SQL permite subconsultas nomeadas chamadas expressões de tabela comuns (nomeadas e projetadas após a implementação do IBM DB2 versão 2; o Oracle chama essas subconsultas de fatoração ). CTEs também podem ser recursivos referindo-se a si próprios; o mecanismo resultante permite percursos de árvore ou gráfico (quando representados como relações) e, de forma mais geral, cálculos de pontos fixos .

Tabela derivada

Uma tabela derivada é o uso de referência a uma subconsulta SQL em uma cláusula FROM. Essencialmente, a tabela derivada é uma subconsulta que pode ser selecionada ou associada a ela. A funcionalidade de tabela derivada permite que o usuário faça referência à subconsulta como uma tabela. A tabela derivada também é conhecida como visualização embutida ou seleção na lista .

No exemplo a seguir, a instrução SQL envolve uma junção da tabela Books inicial com a tabela derivada "Vendas". Esta tabela derivada captura informações de vendas de livros associadas usando o ISBN para unir à tabela Livros. Como resultado, a tabela derivada fornece o conjunto de resultados com colunas adicionais (o número de itens vendidos e a empresa que vendeu os livros):

SELECT b.isbn, b.title, b.price, sales.items_sold, sales.company_nm
FROM Book b
  JOIN (SELECT SUM(Items_Sold) Items_Sold, Company_Nm, ISBN
        FROM Book_Sales
        GROUP BY Company_Nm, ISBN) sales
  ON sales.isbn = b.isbn

Exemplos

Tábua" Consulta Resultado
C1 C2
1 uma
2 b
SELECT * FROM T;
C1 C2
1 uma
2 b
C1 C2
1 uma
2 b
SELECT C1 FROM T;
C1
1
2
C1 C2
1 uma
2 b
SELECT * FROM T WHERE C1 = 1;
C1 C2
1 uma
C1 C2
1 uma
2 b
SELECT * FROM T ORDER BY C1 DESC;
C1 C2
2 b
1 uma
não existe SELECT 1+1, 3*2;
`1 + 1` `3 * 2`
2 6

Dada uma tabela T, a consulta resultará em todos os elementos de todas as linhas da tabela sendo mostrada. SELECT * FROM T

Com a mesma tabela, a consulta resultará nos elementos da coluna C1 de todas as linhas da tabela que estão sendo mostradas. Isso é semelhante a uma projeção em álgebra relacional , exceto que, no caso geral, o resultado pode conter linhas duplicadas. Isso também é conhecido como partição vertical em alguns termos de banco de dados, restringindo a saída da consulta para exibir apenas campos ou colunas especificados. SELECT C1 FROM T

Com a mesma tabela, a consulta resultará em todos os elementos de todas as linhas onde o valor da coluna C1 é '1' sendo mostrado - em termos de álgebra relacional , uma seleção será realizada, por causa da cláusula WHERE. Isso também é conhecido como partição horizontal, restringindo a saída de linhas por uma consulta de acordo com as condições especificadas. SELECT * FROM T WHERE C1 = 1

Com mais de uma tabela, o conjunto de resultados será cada combinação de linhas. Portanto, se duas tabelas são T1 e T2, resultará em todas as combinações de linhas T1 com todas as linhas T2. Por exemplo, se T1 tiver 3 linhas e T2 tiver 5 linhas, o resultado será 15 linhas. SELECT * FROM T1, T2

Embora não esteja no padrão, a maioria dos SGBD permite o uso de uma cláusula select sem uma tabela, fingindo que uma tabela imaginária com uma linha é usada. Isso é usado principalmente para realizar cálculos onde uma tabela não é necessária.

A cláusula SELECT especifica uma lista de propriedades (colunas) por nome ou o caractere curinga (“*”) para significar “todas as propriedades”.

Limitando as linhas de resultados

Freqüentemente, é conveniente indicar um número máximo de linhas que são retornadas. Isso pode ser usado para teste ou para evitar o consumo excessivo de recursos se a consulta retornar mais informações do que o esperado. A abordagem para fazer isso geralmente varia de acordo com o fornecedor.

No ISO SQL: 2003 , os conjuntos de resultados podem ser limitados usando

ISO SQL: 2008 introduziu a FETCH FIRSTcláusula.

De acordo com a documentação do PostgreSQL v.9, uma função de janela SQL "executa um cálculo em um conjunto de linhas da tabela que estão de alguma forma relacionadas à linha atual", de maneira semelhante às funções de agregação. O nome lembra as funções da janela de processamento de sinal . Uma chamada de função de janela sempre contém uma cláusula OVER .

Função de janela ROW_NUMBER ()

ROW_NUMBER() OVERpode ser usado para uma tabela simples nas linhas retornadas, por exemplo, para retornar não mais do que dez linhas:

SELECT * FROM
( SELECT
    ROW_NUMBER() OVER (ORDER BY sort_key ASC) AS row_number,
    columns
  FROM tablename
) AS foo
WHERE row_number <= 10

ROW_NUMBER pode ser não determinístico : se sort_key não for único, cada vez que você executa a consulta, é possível obter diferentes números de linha atribuídos a qualquer linha onde sort_key é o mesmo. Quando sort_key é único, cada linha sempre terá um número de linha único.

Função de janela RANK ()

A RANK() OVERfunção janela atua como ROW_NUMBER, mas pode retornar mais ou menos de n linhas em caso de empate, por exemplo, para retornar os 10 mais jovens:

SELECT * FROM (
  SELECT
    RANK() OVER (ORDER BY age ASC) AS ranking,
    person_id,
    person_name,
    age
  FROM person
) AS foo
WHERE ranking <= 10

O código acima pode retornar mais de dez linhas, por exemplo, se houver duas pessoas da mesma idade, ele pode retornar onze linhas.

Cláusula FETCH FIRST

Desde ISO SQL: 2008, os limites de resultados podem ser especificados como no exemplo a seguir usando a FETCH FIRSTcláusula.

SELECT * FROM T 
FETCH FIRST 10 ROWS ONLY

Essa cláusula atualmente é compatível com CA DATACOM / DB 11, IBM DB2, SAP SQL Anywhere, PostgreSQL, EffiProz, H2, HSQLDB versão 2.0, Oracle 12c e Mimer SQL .

O Microsoft SQL Server 2008 e superior oferece suporteFETCH FIRST , mas é considerado parte da ORDER BYcláusula. Os ORDER BY, OFFSETe FETCH FIRSTcláusulas são todos necessários para este uso.

SELECT * FROM T 
ORDER BY acolumn DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY

Sintaxe não padrão

Alguns DBMSs oferecem sintaxe não padrão em vez de ou em adição à sintaxe padrão SQL. Abaixo, as variantes da consulta de limite simples para diferentes DBMSes são listadas:

SET ROWCOUNT 10
SELECT * FROM T
MS SQL Server (isso também funciona no Microsoft SQL Server 6.5, enquanto o Select top 10 * from T não)
SELECT * FROM T 
LIMIT 10 OFFSET 20
Netezza , MySQL , MariaDB , SAP SQL Anywhere , PostgreSQL (também suporta o padrão, desde a versão 8.4), SQLite , HSQLDB , H2 , Vertica , Polyhedra , Couchbase Server , Snowflake Computing , OpenLink Virtuoso
SELECT * from T 
WHERE ROWNUM <= 10
Oráculo
SELECT FIRST 10 * from T Ingres
SELECT FIRST 10 * FROM T order by a Informix
SELECT SKIP 20 FIRST 10 * FROM T order by c, d Informix (os números das linhas são filtrados após a avaliação do pedido por. A cláusula SKIP foi introduzida em um fixpack v10.00.xC4)
SELECT TOP 10 * FROM T MS SQL Server , SAP ASE , MS Access , SAP IQ , Teradata
SELECT * FROM T 
SAMPLE 10
Teradata
SELECT TOP 20, 10 * FROM T OpenLink Virtuoso (pula 20, entrega os próximos 10)
SELECT TOP 10 START AT 20 * FROM T SAP SQL Anywhere (também suporta o padrão, desde a versão 9.0.1)
SELECT FIRST 10 SKIP 20 * FROM T Firebird
SELECT * FROM T
ROWS 20 TO 30
Firebird (desde a versão 2.1)
SELECT * FROM T
WHERE ID_T > 10 FETCH FIRST 10 ROWS ONLY
DB2
SELECT * FROM T
WHERE ID_T > 20 FETCH FIRST 10 ROWS ONLY
DB2 (novas linhas são filtradas após comparação com a coluna-chave da tabela T)

Paginação de linhas

A paginação de linhas é uma abordagem usada para limitar e exibir apenas uma parte dos dados totais de uma consulta no banco de dados. Em vez de mostrar centenas ou milhares de linhas ao mesmo tempo, o servidor é solicitado apenas uma página (um conjunto limitado de linhas, por exemplo apenas 10 linhas), e o usuário começa a navegar solicitando a próxima página e, em seguida, a próxima , e assim por diante. É muito útil, principalmente em sistemas web, onde não existe uma conexão dedicada entre o cliente e o servidor, de forma que o cliente não precisa esperar para ler e exibir todas as linhas do servidor.

Abordagem de dados na paginação

  • {rows} = Número de linhas em uma página
  • {page_number} = Número da página atual
  • {begin_base_0} = Número da linha - 1 onde a página começa = (page_number-1) * linhas

Método mais simples (mas muito ineficiente)

  1. Selecione todas as linhas do banco de dados
  2. Ler todas as linhas, mas enviar para exibição apenas quando o número_da_linha das linhas lidas estiver entre {begin_base_0 + 1}e{begin_base_0 + rows}
Select * 
from {table} 
order by {unique_key}

Outro método simples (um pouco mais eficiente do que ler todas as linhas)

  1. Selecione todas as linhas do início da tabela até a última linha para exibir ( {begin_base_0 + rows})
  2. Leia as {begin_base_0 + rows}linhas, mas envie para exibição apenas quando o número_da_linha das linhas lidas for maior que{begin_base_0}
SQL Dialeto
select *
from {table}
order by {unique_key}
FETCH FIRST {begin_base_0 + rows} ROWS ONLY
SQL ANSI 2008
PostgreSQL
SQL Server 2012
Derby
Oracle 12c
DB2 12
Mimer SQL
Select *
from {table}
order by {unique_key}
LIMIT {begin_base_0 + rows}
MySQL
SQLite
Select TOP {begin_base_0 + rows} * 
from {table} 
order by {unique_key}
SQL Server 2005
SET ROWCOUNT {begin_base_0 + rows}
Select * 
from {table} 
order by {unique_key}
SET ROWCOUNT 0
Sybase, SQL Server 2000
Select *
    FROM (
        SELECT * 
        FROM {table} 
        ORDER BY {unique_key}
    ) a 
where rownum <= {begin_base_0 + rows}
Oracle 11


Método com posicionamento

  1. Selecione apenas as {rows}linhas começando na próxima linha para exibir ( {begin_base_0 + 1})
  2. Leia e envie para exibir todas as linhas lidas do banco de dados
SQL Dialeto
Select *
from {table}
order by {unique_key}
OFFSET {begin_base_0} ROWS
FETCH NEXT {rows} ROWS ONLY
SQL ANSI 2008
PostgreSQL
SQL Server 2012
Derby
Oracle 12c
DB2 12
Mimer SQL
Select *
from {table}
order by {unique_key}
LIMIT {rows} OFFSET {begin_base_0}
MySQL
MariaDB
PostgreSQL
SQLite
Select * 
from {table} 
order by {unique_key}
LIMIT {begin_base_0}, {rows}
MySQL
MariaDB
SQLite
Select TOP {begin_base_0 + rows}
       *,  _offset=identity(10) 
into #temp
from {table}
ORDER BY {unique_key} 
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
Sybase 12.5.3:
SET ROWCOUNT {begin_base_0 + rows}
select *,  _offset=identity(10) 
into #temp
from {table}
ORDER BY {unique_key} 
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
SET ROWCOUNT 0
Sybase 12.5.2:
select TOP {rows} * 
from (
      select *, ROW_NUMBER() over (order by {unique_key}) as _offset
      from {table}
) xx 
where _offset > {begin_base_0}


SQL Server 2005
SET ROWCOUNT {begin_base_0 + rows}
select *,  _offset=identity(int,1,1) 
into #temp
from {table}
ORDER BY {unique-key}
select * from #temp where _offset > {begin_base_0}
DROP TABLE #temp
SET ROWCOUNT 0
SQL Server 2000
SELECT * FROM (
    SELECT rownum-1 as _offset, a.* 
    FROM(
        SELECT * 
        FROM {table} 
        ORDER BY {unique_key}
    ) a 
    WHERE rownum <= {begin_base_0 + cant_regs}
)
WHERE _offset >= {begin_base_0}
Oracle 11


Método com filtro (é mais sofisticado, mas necessário para um conjunto de dados muito grande)

  1. Selecione então as {rows}linhas com filtro:
    1. Primeira página: selecione apenas as primeiras {rows}linhas, dependendo do tipo de banco de dados
    2. Próxima página: selecione apenas as primeiras {rows}linhas, dependendo do tipo de banco de dados, onde o {unique_key}é maior que {last_val}(o valor de {unique_key}da última linha na página atual)
    3. Página anterior: classifique os dados na ordem inversa, selecione apenas as primeiras {rows}linhas, onde o {unique_key}é menor que {first_val}(o valor de {unique_key}da primeira linha na página atual) e classifique o resultado na ordem correta
  2. Leia e envie para exibir todas as linhas lidas do banco de dados
Primeira página Próxima página Página anterior Dialeto
select *
from {table} 
order by {unique_key}
FETCH FIRST {rows} ROWS ONLY
select * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
FETCH FIRST {rows} ROWS ONLY
select * 
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
   FETCH FIRST {rows} ROWS ONLY
 ) a
 order by {unique_key}
SQL ANSI 2008
PostgreSQL
SQL Server 2012
Derby
Oracle 12c
DB2 12
Mimer SQL
select *
from {table}
order by {unique_key}
LIMIT {rows}
select * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
LIMIT {rows}
select * 
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
   LIMIT {rows}
 ) a
 order by {unique_key}
MySQL
SQLite
select TOP {rows} * 
from {table} 
order by {unique_key}
select TOP {rows} * 
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
select * 
 from (
   select TOP {rows} * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
 ) a
 order by {unique_key}
SQL Server 2005
SET ROWCOUNT {rows}
select *
from {table} 
order by {unique_key}
SET ROWCOUNT 0
SET ROWCOUNT {rows}
select *
from {table} 
where {unique_key} > {last_val}
order by {unique_key}
SET ROWCOUNT 0
SET ROWCOUNT {rows}
 select *
 from (
   select * 
   from {table} 
   where {unique_key} < {first_val}
   order by {unique_key} DESC
 ) a
 order by {unique_key}
 SET ROWCOUNT 0
Sybase, SQL Server 2000
select *
from (
    select * 
    from {table} 
    order by {unique_key}
  ) a 
where rownum <= {rows}
select *
from (
  select * 
  from {table} 
  where {unique_key} > {last_val}
  order by {unique_key}
) a 
where rownum <= {rows}
select * 
 from (
   select *
   from (
     select * 
     from {table} 
     where {unique_key} < {first_val}
     order by {unique_key} DESC
   ) a1
   where rownum <= {rows}
 ) a2
 order by {unique_key}
Oracle 11

Consulta hierárquica

Alguns bancos de dados fornecem sintaxe especializada para dados hierárquicos .

Uma função de janela no SQL: 2003 é uma função agregada aplicada a uma partição do conjunto de resultados.

Por exemplo,

sum(population) OVER( PARTITION BY city )

calcula a soma das populações de todas as linhas com o mesmo valor de cidade da linha atual.

As partições são especificadas usando a cláusula OVER , que modifica o agregado. Sintaxe:

<OVER_CLAUSE> :: =
   OVER ( [ PARTITION BY <expr>, ... ]
          [ ORDER BY <expression> ] )

A cláusula OVER pode particionar e ordenar o conjunto de resultados. A ordenação é usada para funções relativas à ordem, como número_da_linha.

Avaliação de consulta ANSI

O processamento de uma instrução SELECT de acordo com ANSI SQL seria o seguinte:

  1. select g.*
    from users u inner join groups g on g.Userid = u.Userid
    where u.LastName = 'Smith'
    and u.FirstName = 'John'
    
  2. a cláusula FROM é avaliada, uma junção cruzada ou produto cartesiano é produzido para as duas primeiras tabelas na cláusula FROM, resultando em uma tabela virtual como Vtable1
  3. a cláusula ON é avaliada para vtable1; apenas os registros que atendem à condição de junção g.Userid = u.Userid são inseridos em Vtable2
  4. Se uma junção externa for especificada, os registros que foram descartados da vTable2 são adicionados à VTable 3, por exemplo, se a consulta acima for:
    select u.*
    from users u left join groups g on g.Userid = u.Userid
    where u.LastName = 'Smith'
    and u.FirstName = 'John'
    
    todos os usuários que não pertenciam a nenhum grupo seriam adicionados de volta à Vtable3
  5. a cláusula WHERE é avaliada, neste caso, apenas informações de grupo para o usuário John Smith seriam adicionadas a vTable4
  6. o GROUP BY é avaliado; se a consulta acima fosse:
    select g.GroupName, count(g.*) as NumberOfMembers
    from users u inner join groups g on g.Userid = u.Userid
    group by GroupName
    
    vTable5 consistiria em membros retornados de vTable4 organizados pelo agrupamento, neste caso o GroupName
  7. a cláusula HAVING é avaliada para grupos para os quais a cláusula HAVING é verdadeira e inserida em vTable6. Por exemplo:
    select g.GroupName, count(g.*) as NumberOfMembers
    from users u inner join groups g on g.Userid = u.Userid
    group by GroupName
    having count(g.*) > 5
    
  8. a lista SELECT é avaliada e retornada como Vtable 7
  9. a cláusula DISTINCT é avaliada; linhas duplicadas são removidas e retornadas como Vtable 8
  10. a cláusula ORDER BY é avaliada, ordenando as linhas e retornando VCursor9. Este é um cursor e não uma tabela porque ANSI define um cursor como um conjunto ordenado de linhas (não relacional).

Suporte de função de janela por fornecedores de RDBMS

A implementação de recursos de função de janela por fornecedores de bancos de dados relacionais e mecanismos SQL é muito diferente. A maioria dos bancos de dados suporta pelo menos alguns tipos de funções de janela. No entanto, quando olhamos mais de perto, fica claro que a maioria dos fornecedores implementa apenas um subconjunto do padrão. Vamos pegar a poderosa cláusula RANGE como exemplo. Somente Oracle, DB2, Spark / Hive e Google Big Query implementam totalmente esse recurso. Mais recentemente, os fornecedores adicionaram novas extensões ao padrão, por exemplo, funções de agregação de array. Eles são particularmente úteis no contexto de execução de SQL em um sistema de arquivos distribuído (Hadoop, Spark, Google BigQuery), onde temos garantias de co-localidade de dados mais fracas do que em um banco de dados relacional distribuído (MPP). Em vez de distribuir uniformemente os dados por todos os nós, os mecanismos SQL que executam consultas em um sistema de arquivos distribuído podem obter garantias de co-localidade de dados aninhando os dados e, assim, evitando junções potencialmente caras que envolvem embaralhamento pesado pela rede. Funções agregadas definidas pelo usuário que podem ser usadas em funções de janela são outro recurso extremamente poderoso.

Gerando dados em T-SQL

Método para gerar dados com base na união de todos

select 1 a, 1 b union all
select 1, 2 union all
select 1, 3 union all
select 2, 1 union all
select 5, 1

O SQL Server 2008 oferece suporte ao "construtor de linha" especificado no padrão SQL3 ("SQL: 1999")

select *
from (values (1, 1), (1, 2), (1, 3), (2, 1), (5, 1)) as x(a, b)

Referências

Fontes

  • Particionamento horizontal e vertical, Manuais online do Microsoft SQL Server 2000.

links externos