SELECT [ ALL | DISTINCT [ ON ( expressão [, ...] ) ] ]
* | expressão [ AS nome_saída ] [, ...]
[ FROM item_de [, ...] ]
[ WHERE condição ]
[ GROUP BY expressão [, ...] ]
[ HAVING condição [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]
[ ORDER BY expressão [ ASC | DESC | USING operador ] [, ...] ]
[ FOR UPDATE [ OF nome_da_tabela [, ...] ] ]
[ LIMIT { contador | ALL } ]
[ OFFSET início ]
onde item_de pode ser:
[ ONLY ] nome_da_tabela [ * ]
[ [ AS ] aliás [ ( lista_coluna_alias ) ] ]
|
( select )
[ AS ] aliás [ ( lista_coluna_alias ) ]
|
item_de [ NATURAL ] tipo_de_junção item_de
[ ON condição_de_junção | USING ( lista_coluna_junção ) ]
O nome de uma coluna da tabela ou uma expressão.
Especifica outro nome para uma coluna retornada utilizando a cláusula AS. Este nome é utilizado, principalmente, como o título da coluna exibida. Também pode ser utilizado para fazer referência ao valor da coluna nas cláusulas ORDER BY e GROUP BY. Mas o nome_saída não pode ser usado nas cláusulas WHERE e HAVING; nestes casos deve-se escrever novamente a expressão.
A referência a uma tabela, uma subconsulta ou uma cláusula de junção. Veja abaixo para obter detalhes.
Uma expressão booleana produzindo um resultado falso ou verdadeiro. Veja a descrição das cláusulas WHERE e HAVING abaixo.
Um comando SELECT com todas as suas funcionalidades, exceto as cláusulas ORDER BY, FOR UPDATE e LIMIT (mesmo estas podem ser utilizadas quando o SELECT está entre parênteses).
Os itens da cláusula FROM podem conter:
O nome de uma tabela ou de uma visão existente. Se ONLY for especificado, somente esta tabela é consultada. Se ONLY não for especificado a tabela, e todas as suas tabelas descendentes porventura existentes, serão consultadas. O * pode ser apensado ao nome da tabela para indicar que as tabelas descendentes devem ser consultadas, mas na versão corrente este é o comportamento padrão (Nas versões anteriores a 7.1 ONLY era o comportamento padrão).
Um nome substituto para o nome_da_tabela precedente. Um aliás é utilizado para abreviar ou para eliminar ambigüidade em autojunções (onde a mesma tabela é referenciada várias vezes). Se um aliás for escrito, uma lista de aliás de coluna também pode ser escrita para fornecer nomes substitutos para uma ou mais colunas da tabela.
Uma subconsulta pode aparecer na cláusula FROM, agindo como se sua saída fosse criada como uma tabela temporária pela duração do comando SELECT. Observe que a subconsulta deve estar entre parênteses, e que um aliás deve ser fornecido para esta subconsulta.
Um entre [ INNER ] JOIN, LEFT [ OUTER ] JOIN, RIGHT [ OUTER ] JOIN, FULL [ OUTER ] JOIN, ou CROSS JOIN. Para os tipos de junção INNER e OUTER, exatamente um entre NATURAL, ON condição_de_junção, ou USING ( lista_coluna_junção ) deve estar presente. Para CROSS JOIN, nenhum destes itens pode aparecer.
Uma condição de qualificação, similar à condição WHERE, exceto que somente se aplica aos dois itens sendo unidos por esta cláusula JOIN.
A condição USING lista de colunas ( a, b, ... ) é uma forma abreviada da condição ON tabela_esquerda.a = tabela_direita.a AND tabela_esquerda.b = tabela_direita.b ...
O comando SELECT retorna linhas de uma ou mais tabelas. As linhas que satisfazem a condição WHERE são candidatas para seleção; se WHERE for omitido, todas as linhas são candidatas (Veja A cláusula WHERE).
Na verdade, as linhas retornadas não são as linhas produzidas pelas cláusulas FROM/WHERE/GROUP BY/HAVING diretamente; mais precisamente, as linhas da saída são formadas computando-se as expressões de saída do SELECT para cada linha selecionada. O * pode ser escrito na lista de saída como uma abreviação para todas as colunas das linhas selecionadas. Pode-se escrever também nome_da_tabela.* como uma abreviação para as colunas provenientes de apenas uma tabela.
A opção DISTINCT elimina as linhas repetidas do resultado, enquanto que a opção ALL (o padrão) retorna todas as linhas candidatas, incluindo as repetidas.
DISTINCT ON elimina as linhas que correspondem a todas as expressões especificadas, mantendo apenas a primeira linha de cada conjunto de repetidas. As expressões do DISTINCT ON são interpretadas usando as mesmas regras dos itens do ORDER BY; veja abaixo. Observe que a "primeira linha" de cada conjunto não pode ser prevista, a menos que ORDER BY seja usado para garantir que a linha desejada apareça primeiro. Por exemplo,
SELECT DISTINCT ON (local) local, data, condicao
FROM tbl_condicao_climatica
ORDER BY local, data DESC;
exibe a condição climática mais recente para cada local, mas se ORDER BY não tivesse sido usado para forçar uma ordem descendente dos valores da data para cada local, teria sido obtido um relatório com datas aleatórias para cada local.
A cláusula GROUP BY permite dividir a tabela em grupos de linhas que correspondem a um ou mais valores (Veja A cláusula GROUP BY).
A cláusula HAVING permite selecionar somente os grupos de linhas que atendem a uma condição específica (Veja A cláusula HAVING).
A cláusula ORDER BY faz com que as linhas retornadas sejam classificadas na ordem especificada. Se ORDER BY não for especificado, as linhas retornam na ordem que o sistema considera mais fácil de gerar (Veja A cláusula ORDER BY).
As consultas SELECT podem ser combinadas usando os operadores UNION, INTERSECT e EXCEPT. Use parênteses, se for necessário, para determinar a ordem destes operadores.
O operador UNION computa a coleção das linhas retornadas pelas consultas envolvidas. As linhas duplicadas são eliminadas, a não ser que ALL seja especificado (Veja A cláusula UNION).
O operador INTERSECT computa as linhas que são comuns às duas consultas (interseção). As linhas duplicadas são eliminadas, a não ser que ALL seja especificado (Veja A cláusula INTERSECT).
O operador EXCEPT computa as linhas que são retornadas pela primeira consulta, mas que não são retornadas pela segunda consulta. As linhas duplicadas são eliminadas, a não ser que ALL seja especificado (Veja A cláusula EXCEPT).
A cláusula FOR UPDATE permite ao comando SELECT realizar o bloqueio exclusivo das linhas selecionadas.
A cláusula LIMIT permite que retorne para o usuário apenas um subconjunto das linhas produzidas pela consulta (Veja A cláusula LIMIT).
É necessário possuir o privilégio SELECT na tabela para poder ler seus valores (Consulte os comandos GRANT e REVOKE).
A cláusula FROM especifica uma ou mais tabelas de origem para o SELECT. Se múltiplas tabelas de origem forem especificadas o resultado será, conceitualmente, o produto Cartesiano de todas as linhas de todas estas tabelas -- mas, geralmente, condições de qualificação são adicionadas para restringir as linhas retornadas a um pequeno subconjunto do produto Cartesiano.
Quando o item da cláusula FROM é simplesmente o nome de uma tabela, implicitamente são incluídas as linhas das subtabelas desta tabela (filhas que herdam). Especificando-se ONLY causa a supressão das linhas das subtabelas da tabela. Antes do PostgreSQL 7.1 este era o comportamento padrão, e a adição das subtabelas era feita anexando-se um * ao nome da tabela. Este comportamento antigo está disponível através do comando SET SQL_Inheritance TO OFF;
Um item da cláusula FROM pode ser também uma subconsulta entre parênteses (note que uma cláusula aliás é exigida para a subconsulta!). Esta característica é extremamente útil porque esta é a única maneira de se obter múltiplos níveis de agrupamento, agregação ou ordenação em uma única consulta.
Finalmente, um item da cláusula FROM pode ser uma cláusula JOIN, que combina dois itens do FROM (Use parênteses, se for necessário, para determinar a ordem de aninhamento).
O CROSS JOIN e o INNER JOIN são um produto Cartesiano simples, o mesmo que seria obtido listando-se os dois itens no nível superior do FROM. O CROSS JOIN é equivalente ao INNER JOIN ON (TRUE), ou seja, nenhuma linha é removida pela qualificação. Estes tipos de junção são apenas uma notação conveniente, porque não fazem nada que não poderia ser feito usando simplesmente o FROM e o WHERE.
O LEFT OUTER JOIN retorna todas as linhas do produto Cartesiano qualificado (i.e., todas as linhas combinadas que passam pela condição ON), mais uma cópia de cada linha da tabela à esquerda para a qual não há uma linha da tabela à direita que tenha passado pela condição ON. Esta linha da tabela à esquerda é estendida por toda a largura da tabela combinada inserindo-se nulos para as colunas da tabela à direita. Observe que somente as condições ON ou USING do próprio JOIN são consideradas na hora de decidir quais linhas possuem correspondência. Condições ON ou WHERE externas são aplicadas depois.
De forma inversa, o RIGHT OUTER JOIN retorna todas as linhas da junção, mais uma linha para cada linha da tabela à direita sem correspondência (estendida com nulos na tabela à esquerda). Isto é apenas uma conveniência da notação, porque poderia ser convertido em um LEFT OUTER JOIN trocando-se a tabela à direita pela tabela à esquerda.
O FULL OUTER JOIN retorna todas as linhas da junção, mais uma linha para cada linha da tabela à esquerda sem correspondência (estendida com nulos na tabela à direita), mais uma linha da tabela à direita sem correspondência (estendida com nulos na tabela à esquerda)
Para todos os tipos de JOIN, exceto CROSS JOIN, deve-se escrever exatamente um entre ON condição_de_junção, USING ( lista_coluna_junção ), ou NATURAL. A cláusula ON é o caso mais geral: pode ser escrita qualquer expressão de qualificação envolvendo as duas tabelas da junção. A forma USING lista de colunas ( a, b, ... ) é uma abreviação para a condição ON tabela_esquerda.a = tabela_direita.a AND tabela_esquerda.b = tabela_direita.b ... Além disso, USING implica em que somente uma coluna de cada par de colunas equivalentes será incluída na saída do JOIN, e não as duas. NATURAL é uma abreviação para USING quando a lista menciona todas as colunas das tabelas com mesmo nome.
A condição opcional WHERE possui a forma geral:
WHERE expressão_booleana
A expressão_booleana pode ser qualquer expressão que retorna um valor booleano. Em muitos casos esta expressão possui a forma:
expressão op_condição expressão
ou
op_logico expressão
onde op_condição pode ser um entre: =, <, <=, >, >= ou <>, um operador condicional como ALL, ANY, IN, LIKE, ou um operador definido localmente, e op_logico pode ser um entre: AND, OR e NOT. O SELECT ignora todas as linhas para as quais a condição WHERE não retorna TRUE.
O GROUP BY especifica uma tabela agrupada derivada da aplicação desta cláusula:
GROUP BY expressão [, ...]
O GROUP BY condensa em uma única linha todas as linhas selecionadas que compartilham os mesmos valores para as colunas agrupadas. As funções de agregação, caso existam, são computadas através de todas as linhas que pertencem a cada grupo, produzindo um valor separado para cada grupo (enquanto que sem GROUP BY, uma função de agregação produz um único valor computado através de todas as linhas selecionadas). Quando GROUP BY está presente, não é válido uma expressão de saída do SELECT fazer referência a uma coluna não agrupada, exceto dentro de uma função de agregação, porque pode haver mais de um valor possível retornado para uma coluna não agrupada.
Um item do GROUP BY pode ser o nome de uma coluna da entrada, o nome ou o número ordinal de uma coluna da saída (expressão SELECT), ou pode ser uma expressão arbitrária formada pelos valores das colunas da entrada. No caso de haver ambigüidade, o nome no GROUP BY vai ser interpretado como o sendo o nome de uma coluna da entrada, e não como o nome de uma coluna da saída.
A condição opcional HAVING possui a forma geral:
HAVING expressão_booleana
onde expresão_booleana é a mesma que foi especificada para a cláusula WHERE.
HAVING especifica uma tabela agrupada derivada pela eliminação das linhas agrupadas que não satisfazem a expressão_booleana. HAVING é diferente de WHERE: WHERE filtra individualmente as linhas antes da aplicação do GROUP BY, enquanto HAVING filtra os grupos de linhas criados pelo GROUP BY.
Cada coluna referenciada na expressão_booleana 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.
ORDER BY expressão [ ASC | DESC | USING operador ] [, ...]
Um item do ORDER BY pode ser o nome ou o número ordinal de uma coluna da saída (expressão SELECT), ou pode ser uma expressão arbitrária formada por valores da coluna de entrada. No caso de haver ambigüidade, o nome no ORDER BY será interpretado como o nome de uma coluna da saída.
O número ordinal refere-se à posição ordinal (da esquerda para a direita) da coluna do resultado. Esta característica torna possível definir uma ordenação baseada em uma coluna que não possui um nome próprio. Nunca isto é absolutamente necessário, porque é sempre possível atribuir um nome a uma coluna do resultado usando a cláusula AS, como no exemplo abaixo:
SELECT titulo, data_prod + 1 AS newlen FROM filmes ORDER BY newlen;
Também é possível efetuar um ORDER BY por expressões arbitrárias (uma extensão ao SQL92), incluindo campos que não aparecem na lista de resultados do SELECT. Portanto, o seguinte comando é válido:
SELECT nome FROM distribuidores ORDER BY cod;
Uma limitação desta funcionalidade é que uma cláusula ORDER BY aplicada ao resultado de uma consulta com UNION, INTERSECT, ou EXCEPT pode apenas especificar um nome ou um número de coluna, mas não uma expressão.
Observe que se um item do ORDER BY for um nome simples que corresponda tanto ao nome de uma coluna do resultado quanto ao nome de uma coluna da entrada, o ORDER BY vai interpretar como sendo o nome da coluna do resultado. Esta opção é oposta a que é feita pelo GROUP BY na mesma situação. Esta inconsistência é determinada pelo padrão SQL92.
Opcionalmente pode ser utilizada a palavra chave DESC (descendente) ou ASC (ascendente) após cada nome de coluna na cláusula ORDER BY. Se nada for especificado, ASC é assumido por padrão. Alternativamente, um nome de operador de ordenação específico pode ser especificado. ASC é equivalente a USING < e DESC é equivalente a USING >.
O valor nulo possui posição de ordenação maior do que qualquer outro valor do domínio. Em outras palavras, na ordenação ascendente os valores nulos ficam no final, e na ordenação descendente os valores nulos ficam no início.
tabela_consulta UNION [ ALL ] tabela_consulta
[ ORDER BY expressão [ ASC | DESC | USING operador ] [, ...] ]
[ LIMIT { contador | ALL } ]
[ OFFSET início ]
onde tabela_consulta especifica qualquer expressão de seleção sem as cláusulas ORDER BY, FOR UPDATE, ou LIMIT (ORDER BY e LIMIT podem aparecer na subexpressão se estiver entre parênteses. Sem os parênteses estas cláusulas se aplicam ao resultado da UNION, e não na sua expressão de entrada da direita).
O operador UNION computa a coleção (conjunto união) das linhas retornadas pelas consultas envolvidas. Os dois SELECT que representam os operandos diretos do UNION devem produzir o mesmo número de colunas, e as colunas correspondentes devem possuir tipos de dado compatíveis.
O resultado de uma UNION não contém nenhuma linha repetida, a menos que a opção ALL all seja especificada. ALL impede a eliminação das linhas repetidas.
Quando existem vários operadores UNION no mesmo comando SELECT, estes são processados da esquerda para a direita, a menos que outra ordem seja definida pelo uso de parênteses.
Atualmente, FOR UPDATE não deve ser especificado nem no resultado nem nas entradas de uma UNION.
tabela_consulta INTERSECT [ ALL ] tabela_consulta
[ ORDER BY expressão [ ASC | DESC | USING operador ] [, ...] ]
[ LIMIT { contador | ALL } ]
[ OFFSET início ]
onde tabela_consulta especifica qualquer expressão de seleção sem as cláusulas ORDER BY, FOR UPDATE, ou LIMIT.
INTERSECT é semelhante a UNION, exceto que retorna somente as linhas presentes nas saídas das duas consultas, em vez de todas as linhas presentes nas duas consultas.
O resultado do INTERSECT não possui nenhuma linha repetida, a menos que a opção ALL seja especificada. Com ALL, uma linha que possui m repetições em L e n repetições em R aparece min(m,n) vezes.
Quando existem vários operadores INTERSECT no mesmo comando SELECT, estes são processados da esquerda para a direita, a menos que os parênteses estabeleçam outra ordem. INTERSECT tem prevalência sobre UNION --- ou seja, A UNION B INTERSECT C é processado como A UNION (B INTERSECT C), a menos que outra ordem seja estabelecida pelo uso de parênteses..
tabela_consulta EXCEPT [ ALL ] tabela_consulta
[ ORDER BY expressão [ ASC | DESC | USING operador ] [, ...] ]
[ LIMIT { contador | ALL } ]
[ OFFSET início ]
onde tabela_consulta especifica qualquer expressão de seleção sem as cláusulas ORDER BY, FOR UPDATE, ou LIMIT.
EXCEPT é semelhante a UNION, exceto que retorna somente as linhas presentes na saída da consulta à esquerda, mas que não estão presentes na saída da consulta à direita.
O resultado do EXCEPT não possui nenhuma linha repetida, a menos que a opção ALL seja especificada. Com ALL, uma linha que possui m repetições em L e n repetições em R aparece max(m-n,0) vezes.
Quando existem vários operadores EXCEPT no mesmo comando SELECT, estes são processados da esquerda para a direita, a menos que os parênteses estabeleçam outra ordem. EXCEPT possui o mesmo nível de precedência de UNION.
LIMIT { contador | ALL }
OFFSET início
onde contador especifica o número máximo de linhas retornadas, e início especifica o número de linhas a serem saltadas antes de começar a retornar as linhas.
O contador LIMIT permite que seja retornada apenas uma parte das linhas que são geradas pelo resultado da consulta. Se um contador limite for fornecido, não será retornado mais do que este número de linhas. Se um deslocamento for especificado, este número de linhas será saltado antes de começar o retorno das linhas.
Quando LIMIT é usado, aconselha-se utilizar a cláusula ORDER BY para colocar as linhas do resultado dentro de uma ordem única. De outra maneira, será obtido um subconjunto das linhas da consulta impossível de ser previsto --- pode-se estar querendo obter da décima a vigésima linha, mas da décima a vigésima linha de qual ordenação? Não é possível saber qual será a ordenação, a menos que ORDER BY seja especificado.
A partir do PostgreSQL 7.0, o otimizador de consultas leva LIMIT em consideração ao gerar o plano para a consulta, então é muito provável que sejam obtidos planos diferentes (resultando em ordenações diferentes das linhas) dependendo do que seja fornecido para LIMIT e OFFSET. Portanto, utilizar valores diferentes para LIMIT/OFFSET para selecionar subconjuntos diferentes do resultado de uma consulta vai produzir resultados inconsistentes, a menos que seja exigida uma ordenação previsível dos resultados utilizando ORDER BY. Isto não é um erro (bug), isto é uma conseqüência do fato de que o SQL não retorna os resultados de uma consulta em nenhuma ordem específica, a não ser que ORDER BY seja utilizado para definir esta ordem.
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
Une Femme est une Femme | 102 | Jean Luc Godard | 1961-03-12 | Romance
Vertigo | 103 | Paramount | 1958-11-14 | Ação
Becket | 103 | Paramount | 1964-02-03 | Drama
48 Hrs | 103 | Paramount | 1982-10-22 | Ação
War and Peace | 104 | Mosfilm | 1967-02-12 | Drama
West Side Story | 105 | United Artists | 1961-01-03 | Musical
Bananas | 105 | United Artists | 1971-07-13 | Comédia
Yojimbo | 106 | Toho | 1961-06-16 | Drama
There's a Girl in my Soup | 107 | Columbia | 1970-06-11 | Comédia
Taxi Driver | 107 | Columbia | 1975-05-15 | Ação
Absence of Malice | 107 | Columbia | 1981-11-15 | Ação
Storia di una donna | 108 | Westward | 1970-08-15 | Romance
The King and I | 109 | 20th Century Fox | 1956-08-11 | Musical
Das Boot | 110 | Bavaria Atelier | 1981-11-11 | Drama
Bed Knobs and Broomsticks | 111 | Walt Disney | | Musical
(17 rows)
Obter soma da coluna duracao de todos os filmes, agrupando 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 (5 rows)
Obter a soma da coluna duracao de todos os filmes, agrupando os resultados por tipo, mostrando 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 hour';
tipo | total
----------+-------
Comédia | 02:58
Romance | 04:38
(2 rows)
Os dois exemplos mostrados abaixo são formas idênticas de ordenação dos resultados 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 (13 rows)
Este exemplo mostra como obter a união das tabelas distribuidores e atores, restringindo o resultado aos nomes que iniciam pela letra W em cada uma das tabelas. Somente linhas distintas são desejadas, 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
O PostgreSQL permite que seja omitida a cláusula FROM da consulta. Esta funcionalidade da linguagem de consulta PostQuel original foi mantida, sendo muita utilizada para calcular os resultados de expressões com constantes:
SELECT 2+2;
?column?
----------
4
Outros SGBDRs não podem fazer isto, a não ser que seja introduzida uma tabela especial com uma única linha para se efetuar a seleção a partir desta tabela. Uma utilização menos óbvia desta característica é para abreviar consultas normais a uma ou mais tabelas:
SELECT distribuidores.* WHERE distribuidores.nome = 'Westward'; did | nome -----+---------- 108 | Westward
Isso funciona porque um FROM implícito é adicionado para cada tabela que é referenciada na consulta mas não é mencionada no FROM. Ao mesmo tempo em que é uma forma conveniente de abreviar, é fácil de ser usado de forma errada. Por exemplo, a consulta
SELECT distribuidores.* FROM distribuidores d;
deve ser um engano; provavelmente o que se deseja é
SELECT d.* FROM distribuidores d;
em vez da junção sem restrições
SELECT distribuidores.* FROM distribuidores d, distribuidores distribuidores;
que é obtido na realidade. Para ajudar a detectar este tipo de engano, o PostgreSQL 7.1, e posteriores, advertem quando um FROM implícito é usado em uma consulta que também possui uma cláusula FROM explícita.
No padrão SQL92, a palavra chave opcional AS é somente informativa podendo ser omitida sem afetar o significado. O analisador (parser) do PostgreSQL requer a presença desta palavra chave para mudar o nome das colunas da saída, porque a funcionalidade de extensibilidade de tipo ocasiona ambigüidades no analisador dentro deste contexto. Entretanto, AS é opcional nos itens da cláusula FROM.
A frase DISTINCT ON não faz parte do SQL92, assim como LIMIT e OFFSET.
No SQL92, uma cláusula ORDER BY pode utilizar somente os nomes das colunas do resultado, ou números, enquanto uma cláusula GROUP BY pode utilizar somente os nomes das colunas da entrada. O PostgreSQL estende cada uma destas cláusulas para permitir a outra escolha também (mas utiliza a interpretação padrão no caso de ambigüidade). O PostgreSQL também permite que as duas cláusulas especifiquem expressões arbitrárias. Observe que os nomes que aparecem em uma expressão são sempre obtidos a partir dos nomes das colunas da entrada, e não dos nomes das colunas do resultado.