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 SELECT
consultas 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:
-
SELECT
clá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 . -
AS
opcionalmente, fornece um alias para cada coluna ou expressão naSELECT
cláusula. Esta é a operação de renomeação de álgebra relacional . -
FROM
especifica de qual tabela obter os dados. -
WHERE
especifica quais linhas recuperar. Esta é aproximadamente a operação de seleção de álgebra relacional . -
GROUP BY
agrupa 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". SELECT
recupera dados de uma ou mais tabelas ou expressões. As SELECT
instruções padrão não têm efeitos persistentes no banco de dados. Algumas implementações não padrão de SELECT
podem ter efeitos persistentes, como a SELECT INTO
sintaxe 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 SELECT
palavra - 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
FROM
cláusula, que indica as tabelas das quais recuperar os dados. AFROM
cláusula pode incluirJOIN
subcláusulas opcionais para especificar as regras de junção de tabelas. - A
WHERE
cláusula inclui um predicado de comparação, que restringe as linhas retornadas pela consulta. AWHERE
cláusula elimina todas as linhas do conjunto de resultados em que o predicado de comparação não é avaliado como True. - A
GROUP BY
clá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. AWHERE
cláusula é aplicada antes daGROUP BY
cláusula. - A
HAVING
cláusula inclui um predicado usado para filtrar as linhas resultantes daGROUP BY
cláusula. Como atua sobre os resultados daGROUP BY
cláusula, as funções de agregação podem ser usadas noHAVING
predicado da cláusula. - A
ORDER BY
cláusula identifica quais colunas usar para classificar os dados resultantes e em qual direção classificá-los (crescente ou decrescente). Sem umaORDER BY
cláusula, a ordem das linhas retornadas por uma consulta SQL é indefinida. - A
DISTINCT
palavra-chave elimina dados duplicados.
O exemplo a seguir de uma SELECT
consulta 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 AVG
recebe 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 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
SELECT * FROM T;
|
|
||||||||||||
|
SELECT C1 FROM T;
|
|
||||||||||||
|
SELECT * FROM T WHERE C1 = 1;
|
|
||||||||||||
|
SELECT * FROM T ORDER BY C1 DESC;
|
|
||||||||||||
não existe |
SELECT 1+1, 3*2;
|
|
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
- cursores , ou
- adicionando uma função de janela SQL à instrução SELECT
ISO SQL: 2008 introduziu a FETCH FIRST
clá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() OVER
pode 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() OVER
funçã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 FIRST
clá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 BY
cláusula. Os ORDER BY
, OFFSET
e FETCH FIRST
clá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)
- Selecione todas as linhas do banco de dados
- 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)
- Selecione todas as linhas do início da tabela até a última linha para exibir (
{begin_base_0 + rows}
) - 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
- Selecione apenas as
{rows}
linhas começando na próxima linha para exibir ({begin_base_0 + 1}
) - 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)
- Selecione então as
{rows}
linhas com filtro:- Primeira página: selecione apenas as primeiras
{rows}
linhas, dependendo do tipo de banco de dados - 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) - 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
- Primeira página: selecione apenas as primeiras
- 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:
select g.* from users u inner join groups g on g.Userid = u.Userid where u.LastName = 'Smith' and u.FirstName = 'John'
- 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
- 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
- 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:
todos os usuários que não pertenciam a nenhum grupo seriam adicionados de volta à Vtable3
select u.* from users u left join groups g on g.Userid = u.Userid where u.LastName = 'Smith' and u.FirstName = 'John'
- a cláusula WHERE é avaliada, neste caso, apenas informações de grupo para o usuário John Smith seriam adicionadas a vTable4
- o GROUP BY é avaliado; se a consulta acima fosse:
vTable5 consistiria em membros retornados de vTable4 organizados pelo agrupamento, neste caso o GroupName
select g.GroupName, count(g.*) as NumberOfMembers from users u inner join groups g on g.Userid = u.Userid group by GroupName
- 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
- a lista SELECT é avaliada e retornada como Vtable 7
- a cláusula DISTINCT é avaliada; linhas duplicadas são removidas e retornadas como Vtable 8
- 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.