SELECT [ ALL | DISTINCT [ ON ( expressão [, ...] ) ] ] * | expressão [ AS nome_de_saída ] [, ...] [ FROM item_do_from [, ...] ] [ WHERE condição ] [ GROUP BY expressão [, ...] ] [ HAVING condição [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL ] seleção ] [ ORDER BY expressão [ ASC | DESC | USING operador ] [, ...] ] [ LIMIT { contador | ALL } ] [ OFFSET início ] [ FOR UPDATE [ OF nome_da_tabela [, ...] ] ] onde item_do_from pode ser um entre: [ ONLY ] nome_da_tabela [ * ] [ [ AS ] aliás [ ( aliás_de_coluna [, ...] ) ] ] ( seleção ) [ AS ] aliás [ ( aliás_de_coluna [, ...] ) ] nome_da_função ( [ argumento [, ...] ] ) [ AS ] aliás [ ( aliás_de_coluna [, ...] | definição_de_coluna [, ...] ) ] nome_da_função ( [ argumento [, ...] ] ) AS ( definição_de_coluna [, ...] ) item_do_from [ NATURAL ] tipo_de_junção item_do_from [ ON condição_de_junção | USING ( coluna_de_junção [, ...] ) ]
O comando SELECT retorna linhas de uma ou mais tabelas. O processamento geral do comando SELECT está descrito abaixo:
É necessário possuir o privilégio SELECT na tabela para poder ler seus valores. A utilização de FOR UPDATE requer também o privilégio UPDATE.
A cláusula FROM especifica uma ou mais tabelas fonte para o comando SELECT. Se várias fontes forem especificadas, o resultado será o produto cartesiano (junção cruzada) de todas as fontes, mas normalmente são incluídas condições de qualificação para restringir as linhas retornadas a um pequeno subconjunto do produto cartesiano.
A cláusula FROM pode conter os seguintes elementos:
A cláusula opcional WHERE possui a forma geral
WHERE condição
onde condição é uma expressão que produz um resultado do tipo boolean [5] . Todas as linhas que não satisfazem a esta condição são eliminadas da saída. A linha satisfaz a condição se retorna verdade quando os valores reais da linha são colocados no lugar das variáveis que os referenciam.
A cláusula opcional GROUP BY possui a forma geral
GROUP BY expressão [, ...]
A cláusula GROUP BY condensa em uma única linha todas as linhas selecionadas que compartilham os mesmos valores para as expressões de agrupamento. A expressão pode ser o nome de uma coluna da entrada, ou o nome ou o número ordinal de uma coluna da saída (lista de itens do SELECT), ou uma expressão arbitrária formada por valores das colunas da entrada. Havendo ambigüidade, o nome na cláusula GROUP BY será interpretado como sendo o nome da coluna da entrada, e não o nome da coluna da saída.
As funções de agregação, caso sejam usadas, são computadas entre todas as linhas que constituem cada grupo, produzindo um valor separado para cada grupo (enquanto sem GROUP BY, uma agregação produz um único valor computado entre todas as linhas selecionadas). Quando GROUP BY está presente, não é válido a lista de expressões do SELECT fazer referência a colunas não agrupadas, exceto dentro das funções de agregação, uma vez que haveria mais de um valor possível retornado para uma coluna não agrupada.
A cláusula opcional HAVING possui a forma geral
HAVING condição
onde condição é especificada da mesma forma que na cláusula WHERE.
A cláusula HAVING elimina os grupos de linhas que não satisfazem a condição. A cláusula HAVING é diferente da cláusula WHERE: WHERE filtra individualmente as linhas antes do GROUP BY ser aplicado, enquanto HAVING filtra grupos de linhas criados pelo GROUP BY. Cada coluna referenciada na condição deve referenciar sem ambigüidade uma coluna de agrupamento, a menos que a referência apareça dentro de uma função de agregação.
A presença da cláusula HAVING torna a consulta uma consulta agrupada, mesmo que não exista a cláusula GROUP BY. É o mesmo que acontece quando a consulta contém funções de agregação mas não possui a cláusula GROUP BY. Todas as linhas selecionadas são consideradas como formando um único grupo, e tanto a lista do SELECT quanto a cláusula HAVING somente podem fazer referência a colunas da tabela dentro de funções de agregação. Este tipo de consulta gera uma única linha se a condição da cláusula HAVING for verdade, ou nenhuma linha se não for verdade.
A cláusula UNION possui a forma geral
comando_de_seleção UNION [ ALL ] comando_de_seleção
onde comando_de_seleção é qualquer comando SELECT sem as cláusulas ORDER BY, LIMIT e FOR UPDATE (as cláusulas ORDER BY e LIMIT podem ser aplicadas a uma subexpressão se esta estiver entre parênteses. Sem os parênteses, estas cláusulas são consideradas como aplicadas ao resultado da cláusula UNION, e não à sua expressão de entrada à direita).
O operador UNION computa o conjunto formado pela união das linhas retornadas pelos comandos SELECT envolvidos. Uma linha está presente no conjunto união dos dois conjuntos de resultados se estiver presente em pelo menos um destes dois conjuntos de resultados. Os dois comandos SELECT que representam os operandos diretos do operador UNION devem produzir o mesmo número de colunas, e as colunas correspondentes devem possuir tipos de dado compatíveis.
O resultado do operador UNION não contém nenhuma linha duplicada, a menos que a opção ALL seja especificada. ALL não permite a eliminação das duplicatas.
Havendo vários operadores UNION no mesmo comando SELECT, estes são avaliados da esquerda para a direita, a menos que os parênteses indiquem o contrário.
Atualmente não pode ser especificado FOR UPDATE nem para o resultado do operador UNION nem para qualquer entrada do operador UNION.
A cláusula INTERSECT possui a forma geral
comando_de_seleção INTERSECT [ ALL ] comando_de_seleção
onde comando_de_seleção é qualquer comando SELECT sem as cláusulas ORDER BY, LIMIT e FOR UPDATE.
O operador INTERSECT computa o conjunto formado pela interseção das linhas retornadas pelos comandos SELECT envolvidos. Uma linha está na interseção dos dois conjuntos de resultados se estiver presente nos dois conjuntos de resultados.
O resultado do operador INTERSECT não contém nenhuma linha duplicada, a menos que a opção ALL seja especificada. Usando ALL, uma linha contendo m duplicatas na tabela à esquerda e n duplicatas na tabela à direita, aparece min(m,n) vezes no conjunto de resultados.
Havendo vários operadores INTERSECT no mesmo comando SELECT, estes são avaliados da esquerda para a direita, a menos que os parênteses indiquem outra ordem. O operador INTERSECT tem nível de precedência superior ao do operador UNION, ou seja, A UNION B INTERSECT C é lido como A UNION (B INTERSECT C).
A cláusula EXCEPT possui a forma geral
comando_de_seleção EXCEPT [ ALL ] comando_de_seleção
onde comando_de_seleção é qualquer comando SELECT sem as cláusulas ORDER BY, LIMIT e FOR UPDATE.
O operador EXCEPT computa o conjunto de linhas presentes no resultado do comando SELECT à esquerda, mas que não estão presentes no resultado do comando à direita.
O resultado do operador EXCEPT não contém nenhuma linha duplicada, a menos que a cláusula ALL seja especificada. Usando ALL, uma linha que possua m duplicatas na tabela à esquerda e n duplicatas na tabela à direita aparece max(m-n,0) vezes no conjunto de resultados.
Havendo vários operadores EXCEPT no mesmo comando SELECT, estes são processados da esquerda para a direita, a menos que os parênteses especifiquem outra ordem. O operador EXCEPT possui o mesmo nível de precedência do operador UNION.
A lista do SELECT (entre as palavras chave SELECT e FROM) especifica expressões que formam as linhas de saída do comando SELECT. As expressões podem (e geralmente fazem) referenciar colunas computadas na cláusula FROM. Usando a cláusula AS nome_de_saída, pode ser especificado outro nome para uma coluna da saída. Este nome é usado, principalmente, como rótulo da coluna mostrada. Também pode ser usado para fazer referência ao valor da coluna nas cláusulas ORDER BY e GROUP BY, mas não nas cláusulas WHERE e HAVING; nestas, a expressão deve ser escrita.
Em vez da expressão pode ser escrito * na lista de saída, como abreviação para todas as colunas das linhas selecionadas. Também pode ser escrito nome_da_tabela.* como abreviação das colunas provenientes apenas desta tabela.
A cláusula opcional ORDER BY possui a forma geral
ORDER BY expressão [ ASC | DESC | USING operador ] [, ...]
onde expressão pode ser o nome ou o número ordinal de uma coluna da saída (item da lista do SELECT), ou pode ser uma expressão arbitrária formada por valores das colunas da entrada.
A cláusula ORDER BY faz as linhas do resultado serem classificadas de acordo com as expressões especificadas. Se duas linhas são iguais de acordo com a expressão mais à esquerda, estas são comparadas de acordo com a próxima expressão, e assim por diante. Se forem iguais de acordo com todas as expressões especificadas, são retornadas em uma ordem dependente da implementação.
O número ordinal se refere à posição ordinal (esquerda para a direita) da coluna do resultado. Esta funcionalidade torna possível definir uma ordenação baseada em uma coluna que não possui um nome único. Isto nunca é absolutamente necessário, porque sempre é possível atribuir um nome à coluna do resultado usando a cláusula AS.
Também é possível utilizar expressões arbitrárias na cláusula ORDER BY, incluindo colunas que não aparecem na lista de resultado do SELECT. Portanto, o seguinte comando é válido:
SELECT nome FROM distribuidores ORDER BY codigo;
A limitação desta funcionalidade é que a cláusula ORDER BY aplicada ao resultado de UNION, INTERSECT ou EXCEPT pode especificar apenas nomes de coluna ou números, mas não expressões.
Se a expressão no ORDER BY for simplesmente um nome correspondendo tanto ao nome de uma coluna do resultado quanto ao nome de uma coluna da entrada, o ORDER BY interpreta como sendo o nome da coluna do resultado. Esta é a escolha oposta à feita pelo GROUP BY na mesma situação. Esta incoerência existe para ficar compatível com o padrão SQL.
Pode ser adicionada, opcionalmente, a palavra chave ASC (ascendente) ou DESC (descendente) após cada expressão na cláusula ORDER BY. Se nenhuma das duas for especificada, ASC é assumido por padrão. Como alternativa, pode ser especificado o nome de um operador de ordenação específico na cláusula USING. Geralmente ASC é equivalente a USING < e geralmente DESC é equivalente a USING > (Mas o criador de um tipo de dado definido pelo usuário pode definir exatamente qual é a ordem de classificação padrão, podendo corresponder a operadores com outros nomes).
O valor nulo é classificado em uma posição mais alta do que qualquer outro valor. Em outras palavras, na ordem de classificação ascendente os valores nulos ficam no final, e na ordem de classificação descendente os valores nulos ficam no início. [6]
Dados na forma de cadeias de caracteres são classificados de acordo com a ordem de classificação (collation [7] ) estabelecida quando o agrupamento de bancos de dados foi inicializado.
A cláusula LIMIT consiste em duas subcláusulas independentes:
LIMIT { contador | ALL } OFFSET início
onde contador especifica o número máximo de linhas a serem retornadas, enquanto início especifica o número de linhas a serem puladas antes de começar a retornar as linhas. Quando as duas são especificadas, as início primeiras linhas são puladas antes de começar a contar as contador linhas a serem retornadas.
Ao se usar a cláusula LIMIT é uma boa idéia usar também a cláusula ORDER BY para colocar as linhas do resultado dentro de uma ordem única. Caso contrário será retornado um subconjunto imprevisível de linhas da consulta — pode-se estar querendo receber da décima a vigésima linha, mas da décima a vigésima em que ordem? Não é possível saber qual será a ordem, a não ser que ORDER BY seja especificado.
O planejador de comandos leva LIMIT em consideração ao gerar o plano da consulta, por isso é muito provável serem obtidos planos diferentes (produzindo linhas em ordens diferentes) dependendo do que for especificado para LIMIT e OFFSET. Portanto, utilizar valores diferentes para LIMIT/OFFSET para selecionar subconjuntos diferentes do resultado da consulta produz resultados inconsistentes, a não ser que se obrigue uma ordem previsível para os resultados utilizando ORDER BY. Isto não está errado; isto é uma conseqüência direta do fato do SQL não prometer retornar os resultados de uma consulta em nenhuma ordem específica, a não ser que ORDER BY seja utilizado para impor esta ordem.
Se for especificada a cláusula DISTINCT, todas as linhas duplicadas são removidas do conjunto de resultados (é mantida uma linha para cada grupo de duplicatas). A cláusula ALL especifica o oposto: todas as linhas são mantidas; este é o padrão.
DISTINCT ON ( expressão [, ...] ) preserva apenas a primeira linha de cada conjunto de linhas onde as expressões fornecidas forem iguais. As expressões em DISTINCT ON são interpretadas usando as mesmas regras da cláusula ORDER BY (veja acima). Deve ser observado que a "primeira linha" de cada conjunto é imprevisível, a menos que seja utilizado ORDER BY para garantir que a linha desejada apareça na frente. Por exemplo,
SELECT DISTINCT ON (local) local, data, condicao FROM tbl_condicao_climatica ORDER BY local, data DESC;
mostra o relatório de condição climática mais recente para cada local, mas se não tivesse sido usado ORDER BY para obrigar a ordem descendente dos valores da data para cada local, teria sido obtido um relatório com datas imprevisíveis para cada local.
As expressões em DISTINCT ON devem corresponder às expressões mais à esquerda no ORDER BY. A cláusula ORDER BY normalmente contém expressões adicionais para determinar a precedência desejada das linhas dentro de cada grupo DISTINCT ON.
A cláusula FOR UPDATE possui a forma
FOR UPDATE [ OF nome_da_tabela [, ...] ]
A cláusula FOR UPDATE faz as linhas selecionadas pelo comando SELECT serem bloqueadas como se fosse para atualização. Isto impede a modificação ou exclusão destas linhas por outras transações até a transação corrente terminar. Ou seja, outras transações tentando usar os comandos UPDATE, DELETE ou SELECT FOR UPDATE nestas linhas ficam bloqueadas até a transação corrente terminar. Também, se um comando UPDATE, DELETE, ou SELECT FOR UPDATE de outra transação já tiver bloqueado uma ou várias destas linhas, o SELECT FOR UPDATE fica aguardando a outra transação completar e, então, bloqueia e retorna a linha atualizada (ou nenhuma linha, se a linha foi excluída). Para obter mais explicações veja o Capítulo 12 .
Se forem especificados nomes de tabelas na cláusula FOR UPDATE, então somente as linhas oriundas destas tabelas são bloqueadas; todas as outras tabelas usadas no SELECT são simplesmente lidas como de costume.
FOR UPDATE não pode ser utilizado nos contextos onde as linhas retornadas não podem ser claramente identificadas com as linhas individuais da tabela; por exemplo, não pode ser utilizado junto com agregações.
FOR UPDATE pode estar antes de LIMIT para manter a compatibilidade com as versões do PostgreSQL anteriores a 7.3. Entretanto, será executado após o LIMIT e, portanto, este é o lugar adequado para ser escrito.
Para efetuar a junção da tabela filmes com a tabela distribuidores:
=> SELECT f.titulo, f.did, d.nome, f.data_prod, f.tipo -> FROM distribuidores d, filmes f -> WHERE f.did = d.did titulo | did | nome | data_prod | tipo -------------------+-----+--------------+------------+---------- The Third Man | 101 | British Lion | 1949-12-23 | Drama The African Queen | 101 | British Lion | 1951-08-11 | Romance ...
Para somar a coluna duracao de todos os filmes, e agrupar os resultados por tipo:
=> SELECT tipo, sum(duracao) AS total FROM filmes GROUP BY tipo; tipo | total ----------+------- Ação | 07:34 Comédia | 02:58 Drama | 14:28 Musical | 06:42 Romance | 04:38
Para somar a coluna duracao de todos os filmes, agrupar os resultados por tipo, e mostrar apenas os grupos com total inferior a 5 horas:
=> SELECT tipo, sum(duracao) AS total -> FROM filmes -> GROUP BY tipo -> HAVING sum(duracao) < interval '5 hours'; tipo | total ----------+------- Comédia | 02:58 Romance | 04:38
Os dois exemplos a seguir são formas idênticas de classificação dos resultados individuais de acordo com o conteúdo da segunda coluna (nome):
=> SELECT * FROM distribuidores ORDER BY nome; => SELECT * FROM distribuidores ORDER BY 2; did | nome -----+------------------ 109 | 20th Century Fox 110 | Bavaria Atelier 101 | British Lion 107 | Columbia 102 | Jean Luc Godard 113 | Luso filmes 104 | Mosfilm 103 | Paramount 106 | Toho 105 | United Artists 111 | Walt Disney 112 | Warner Bros. 108 | Westward
O próximo exemplo mostra como obter a união da tabela distribuidores com a tabela atores, restringindo o resultado aos nomes que iniciam pela letra W em cada uma das tabelas. Somente são desejadas linhas distintas, por isso a palavra chave ALL é omitida:
distribuidores atores: did | nome id | nome -----+-------------- ----+---------------- 108 | Westward 1 | Woody Allen 111 | Walt Disney 2 | Warren Beatty 112 | Warner Bros. 3 | Walter Matthau ... ... => SELECT distribuidores.nome -> FROM distribuidores -> WHERE distribuidores.nome LIKE 'W%' -> UNION -> SELECT atores.nome -> FROM atores -> WHERE atores.nome LIKE 'W%'; nome ---------------- Walt Disney Walter Matthau Warner Bros. Warren Beatty Westward Woody Allen
Este exemplo mostra como usar uma função na cláusula FROM, com e sem uma lista de definição de colunas:
=> CREATE FUNCTION distribuidores(int) RETURNS SETOF distribuidores AS ' '> SELECT * FROM distribuidores WHERE did = $1; '> ' LANGUAGE SQL; SELECT * FROM distribuidores(111); did | nome -----+------------- 111 | Walt Disney => CREATE FUNCTION distribuidores_2(int) RETURNS SETOF record AS ' '> SELECT * FROM distribuidores WHERE did = $1; '> ' LANGUAGE SQL; SELECT * FROM distribuidores_2(111) AS (f1 int, f2 text); f1 | f2 -----+------------- 111 | Walt Disney
Obviamente, o comando SELECT é compatível com o padrão SQL. Entretanto, existem algumas extensões e algumas funcionalidades faltando.
O PostgreSQL permite omitir a cláusula FROM. Tem uso direto no cômputo de resultados de expressões simples:
=> SELECT 2+2; ?column? ---------- 4
Alguns outros bancos de dados SQL não podem fazer isto, a não ser introduzindo uma tabela fictícia de uma linha para executar o comando SELECT.
Uma utilização menos óbvia desta funcionalidade é abreviar comandos SELECT comuns de tabelas:
=> SELECT distribuidores.* WHERE distribuidores.nome = 'Westward'; did | nome -----+---------- 108 | Westward
Isso funciona porque é adicionado um item implícito no FROM para cada tabela que é referenciada nas outras partes do comando SELECT, mas que não é mencionada no FROM.
Ao mesmo tempo em que é uma forma conveniente de abreviar, é fácil ser usado incorretamente. Por exemplo, o comando
SELECT distribuidores.* FROM distribuidores d;
provavelmente deve ser um engano; é mais provável que se deseje
SELECT d.* FROM distribuidores d;
do que a junção sem restrições
SELECT distribuidores.* FROM distribuidores d, distribuidores distribuidores;
que seria obtida na verdade. Para ajudar a detectar este tipo de engano, o PostgreSQL adverte se uma funcionalidade FROM implícita é utilizada em um comando SELECT que também contenha uma cláusula FROM explícita. Também é possível desabilitar a funcionalidade de FROM-implícito definindo a parâmetro ADD_MISSING_FROM como falso.
No padrão SQL, a palavra chave opcional AS é sem efeito, podendo ser omitida sem afetar o significado. O analisador do PostgreSQL requer esta palavra chave quando uma coluna da saída é renomeada, porque a funcionalidade de extensividade de tipo conduz o analisador a ambigüidades caso não esteja presente. Entretanto, AS é opcional nos itens do FROM.
No padrão SQL-92, a cláusula ORDER BY somente pode utilizar nomes ou números das colunas do resultado, enquanto a cláusula GROUP BY somente pode utilizar expressões baseadas nos nomes das colunas da entrada. O PostgreSQL estende estas duas cláusulas para permitir, também, a outra escolha (mas utiliza a interpretação padrão se houver ambigüidade). O PostgreSQL também permite que as duas cláusulas especifiquem expressões arbitrárias. Deve ser observado que os nomes que aparecem na expressão sempre são considerados como nomes das colunas da entrada, e não como nomes das colunas do resultado.
O SQL:1999 utiliza uma definição um pouco diferente, que não é inteiramente compatível com o SQL-92. Entretanto, na maioria dos casos o PostgreSQL interpreta uma expressão presente em ORDER BY ou GROUP BY da mesma maneira que o SQL:1999.
[1] |
Oracle — deve ser especificado DISTINCT ou UNIQUE se for desejado que o Oracle retorne apenas uma cópia de cada conjunto de linhas duplicadas selecionadas (esta duas palavras chave são sinônimos). As linhas duplicadas são aquelas com valores correspondentes para cada expressão na lista de seleção; DISTINCT não pode ser especificado quando a lista de seleção contém colunas LOB. Oracle9i SQL Reference - Release 2 (9.2) - Part Number A96540-02 (N. do T.) |
[2] |
SQL Server — DISTINCT especifica que somente linhas únicas podem aparecer no conjunto de resultados. Os valores nulos são considerados iguais para as finalidades da palavra chave DISTINCT. SQL Server Books Online (N. do T.) |
[3] |
SQL Server — TOP n [PERCENT] especifica que somente as primeiras n linhas do conjunto de resultados devem ser retornadas. n é um inteiro entre 0 e 4294967295. Se também for especificado PERCENT, somente devem ser retornados os primeiros n porcentos de linhas do conjunto de resultados. Quando especificado com PERCENT, n deve ser um inteiro entre 0 e 100. Se a consulta incluir a cláusula ORDER BY, as primeiras n linhas (ou n porcento das linhas) ordenadas pela cláusula ORDER BY são retornadas. Se a consulta não possuir a cláusula ORDER BY, a ordem das linhas é arbitrária. SQL Server Books Online (N. do T.) |
[4] |
Oracle — A cláusula FOR UPDATE permite bloquear as linhas selecionadas, não permitindo assim que outros usuários bloqueiem ou atualizem estas linhas até a transação terminar. Esta cláusula somente pode ser especificada no comando SELECT de nível mais alto (não em subseleções). Esta cláusula não pode ser especificada junto com as seguintes construções: o operador DISTINCT, expressão de CURSOR, operadores de conjunto, cláusula GROUP BY e funções de agregação. Oracle9i SQL Reference - Release 2 (9.2) - Part Number A96540-02 (N. do T.) |
[5] |
SQL Server — predicado é uma expressão que é avaliada como TRUE, FALSE ou UNKNOWN. Os predicados são usados nas condições de procura das cláusulas WHERE e HAVING, e nas condições de junção das cláusulas FROM. Veja também BETWEEN, CONTAINS, EXISTS, FREETEXT, IN, IS [NOT] NULL e LIKE. SQL Server Books Online (N. do T.) |
[6] |
No PostgreSQL, no Oracle e no DB2 o valor nulo é classificado em uma posição mais alta que os demais valores, mas no SQL Server o valor nulo é classificado em uma posição mais baixa que os demais valores. O Oracle permite especificar NULLS FIRST e NULLS LAST, para cada coluna, na cláusula ORDER BY. (N. do T.) |
[7] |
collation; collating sequence — Um método para comparar duas cadeias de caracteres comparáveis. Todo conjunto de caracteres possui seu collation padrão. (Second Informal Review Draft) ISO/IEC 9075:1992, Database Language SQL- July 30, 1992. (N. do T.) |