SELECT

Nome

SELECT -- retorna linhas de uma tabela ou de uma visão

Sinopse

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 [, ...] ) ]

Descrição

O comando SELECT retorna linhas de uma ou mais tabelas. O processamento geral do comando SELECT está descrito abaixo:

  1. Todos os elementos da lista FROM são computados; cada elemento na lista FROM é uma tabela real ou virtual. Quando é especificado mais de um elemento na lista FROM, é feita uma junção cruzada entre estes elementos (Veja a Cláusula FROM abaixo).
  2. Se for especificada a cláusula WHERE, todas as linhas que não satisfazem a condição são eliminadas da saída (Veja a Cláusula WHERE abaixo).
  3. Se for especificada a cláusula GROUP BY, a saída é dividida em grupos de linhas que correspondem a um ou mais valores. Se a cláusula HAVING estiver presente, são eliminados os grupos que não satisfazem à condição especificada (Veja a Cláusula GROUP BY e a Cláusula HAVING abaixo).
  4. Usando os operadores UNION, INTERSECT e EXCEPT podem ser combinadas as saídas de vários comandos SELECT para formar um único conjunto de resultados. O operador UNION retorna todas as linhas presentes em um ou nos dois conjuntos de resultados. O operador INTERSECT retorna todas as linhas presentes nos dois conjuntos de resultados. O operador EXCEPT retorna as linhas presentes no primeiro conjunto de resultados mas não no segundo. Em todos estes três casos as linhas duplicadas são eliminadas, a menos que ALL seja especificado (Veja a Cláusula UNION , a Cláusula INTERSECT e Cláusula EXCEPT abaixo).
  5. As linhas de saída reais são computadas utilizando as expressões de saída do comando SELECT para cada linha selecionada (Veja a Lista do SELECT abaixo).
  6. Se for especificada a cláusula ORDER BY, as linhas retornadas são classificadas segundo a ordem especificada. Se a cláusula ORDER BY não for especificada, as linhas são retornadas na ordem em que o sistema considerar mais rápido de produzir (Veja a Cláusula ORDER BY abaixo).
  7. A cláusula DISTINCT remove do resultado as linhas duplicadas [1] [2] . A cláusula DISTINCT ON remove as linhas que correspondem a todas as expressões especificadas. A cláusula ALL (o padrão) retorna todas as linhas candidatas, incluindo as duplicadas (Veja a Cláusula DISTINCT abaixo).
  8. Se for especificada a cláusula LIMIT ou a cláusula OFFSET, o comando SELECT retorna somente um subconjunto das linhas do resultado (Veja a Cláusula LIMIT abaixo) [3] .
  9. A cláusula FOR UPDATE faz o comando SELECT bloquear as linhas selecionadas contra atualizações concorrentes (Veja a Cláusula FOR UPDATE abaixo) [4] .

É 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.

Parâmetros

Cláusula FROM

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:

nome_da_tabela
O nome (opcionalmente qualificado pelo esquema) de uma tabela ou de uma visão existente. Se a cláusula ONLY for especificada, somente esta tabela será varrida. Se a cláusula ONLY não for especificada, esta tabela e todas as suas tabelas descendentes (se existirem) serão varridas. Pode ser anexado um * ao nome da tabela para indicar que as tabelas descendentes devem ser varridas, mas na versão corrente este é o comportamento padrão; nas versões anteriores a 7.1 o comportamento padrão era ONLY. O comportamento padrão pode ser modificado mudando o valor da opção de configuração sql_interitance.
aliás
Um nome substituto para o item da cláusula FROM contendo o aliás. O aliás é utilizado para abreviar, ou para eliminar ambigüidade em auto-junções (onde a mesma tabela é varrida várias vezes). Quando se fornece um aliás, o nome verdadeiro da tabela ou da função fica totalmente escondido; se, por exemplo, for declarado FROM foo AS f, o restante do comando SELECT deve fazer referência a este item do FROM como f, e não como foo. Se for escrito um aliás, também pode ser escrita uma lista de aliases de coluna para fornecer nomes substitutos para uma ou mais colunas da tabela.
seleção
Pode haver sub-SELECT na cláusula FROM. Atua como se sua saída fosse criada como uma tabela temporária pela duração deste único comando SELECT. Deve ser observado que o sub-SELECT deve estar entre parênteses, e que deve ser especificado um aliás para o mesmo.
nome_da_função
Podem estar presentes na cláusula FROM chamadas de função (É especialmente útil no caso das funções que retornam um conjunto de resultados, mas pode ser usada qualquer função). Atua como se a sua saída fosse criada como uma tabela temporária pela duração deste único comando SELECT. Também pode ser utilizado um aliás. Se for escrito um aliás, também pode ser escrita uma lista de aliases de coluna para fornecer nomes substitutos para um ou mais atributos do tipo composto retornado pela função. Se a função tiver sido definida como retornando o tipo de dado record então deve estar presente um aliás, ou a palavra chave AS seguida por uma lista de definições de coluna na forma ( nome_de_coluna tipo_de_dado [, ... ] ). A lista de definições de coluna deve corresponder ao número e tipo reais das colunas retornadas pela função.
tipo_de_junção
Um entre
  • [ INNER ] JOIN
  • LEFT [ OUTER ] JOIN
  • RIGHT [ OUTER ] JOIN
  • FULL [ OUTER ] JOIN
  • CROSS JOIN
Para os tipos de junção INNER e OUTER deve ser especificada uma condição de junção designando exatamente um entre NATURAL, ON condição_de_junção ou USING (coluna_de_junção [, ...]). Veja abaixo o significado. Para CROSS JOIN, nenhuma destas cláusulas pode estar presente. A cláusula JOIN combina dois itens da cláusula FROM. Se for necessário devem ser utilizados parênteses para determinar a ordem de aninhamento. Na ausência de parênteses, a cláusula JOIN aninha da esquerda para a direita. Em todos os casos a cláusula JOIN tem nível de precedência superior ao das vírgulas que separam os itens da cláusula FROM. CROSS JOIN e INNER JOIN produzem um produto cartesiano simples, o mesmo resultado obtido listando os dois itens no nível superior da cláusula FROM, mas restrito pela condição de junção (se houver). CROSS JOIN é equivalente a INNER JOIN ON (TRUE), ou seja, nenhuma linha é removida pela qualificação. Estes tipos de junção são apenas uma notação conveniente, uma vez que não fazem nada que não poderia ser feito usando simplesmente FROM e WHERE. LEFT OUTER JOIN retorna todas as linhas presentes no produto cartesiano qualificado (ou seja, todas as linhas combinadas que passam pela sua condição de junção), mais uma cópia de cada linha da tabela à esquerda para a qual não há linha na tabela à direita que passe pela condição de junção. As linhas da tabela à esquerda são estendidas por toda a largura da tabela de junção, inserindo valores nulos para as colunas da tabela à direita. Deve ser observado que somente a condição da própria cláusula JOIN é considerada ao decidir quais linhas possuem correspondência. As condições externas são aplicadas depois. De forma inversa, 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 à esquerda). É apenas uma notação conveniente, uma vez que pode ser convertido em LEFT OUTER JOIN trocando as entradas à direita e à esquerda. 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 à direita), mais uma linha para cada linha da tabela à direita sem correspondência (estendida com nulos à esquerda).
ON condição_de_junção
A condição_de_junção é uma expressão que resulta em um valor do tipo boolean (semelhante à cláusula WHERE) que especifica quais linhas da junção são consideradas correspondentes.
USING (coluna_de_junção [, ...])
A cláusula com a forma USING ( a, b, ... ) é uma abreviação de ON tabela_à_esquerda.a = tabela_à_direita.a AND tabela_à_esquerda.b = tabela_à_direita.b .... USING também implica que somente será incluída na saída da junção uma de cada par de colunas equivalentes, e não as duas.
NATURAL
NATURAL é uma forma abreviada para a lista USING mencionando todas as colunas das duas tabelas que possuem o mesmo nome.

Cláusula WHERE

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.

Cláusula GROUP BY

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.

Cláusula HAVING

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.

Cláusula UNION

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.

Cláusula INTERSECT

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).

Cláusula EXCEPT

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.

Lista do SELECT

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.

Cláusula ORDER BY

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.

Cláusula LIMIT

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.

Cláusula DISTINCT

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.

Cláusula FOR UPDATE

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.

Exemplos

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

Compatibilidade

Obviamente, o comando SELECT é compatível com o padrão SQL. Entretanto, existem algumas extensões e algumas funcionalidades faltando.

Cláusula FROM omitida

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.

A palavra chave AS

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.

Espaço de nomes disponível para GROUP BY e ORDER BY

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.

Cláusulas fora do padrão

As cláusulas DISTINCT ON, LIMIT e OFFSET não são definidas no padrão SQL.

Notas

[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.)

SourceForge.net Logo