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 zero ou mais tabelas. O processamento geral do comando SELECT está descrito abaixo:
Todos os elementos da lista FROM são computados; cada elemento na lista FROM é uma tabela real ou virtual. Se for especificado mais de um elemento na lista FROM será feita a junção cruzada destes elementos (Consulte a Cláusula FROM abaixo).
Se for especificada a cláusula WHERE, todas as linhas que não satisfazem a condição serão eliminadas da saída (Consulte a Cláusula WHERE abaixo).
Se for especificada a cláusula GROUP BY, a saída será dividida em grupos de linhas que correspondem a um ou mais valores. Se a cláusula HAVING estiver presente, serão eliminados os grupos que não satisfazem à condição especificada (Consulte a Cláusula GROUP BY e a Cláusula HAVING abaixo). [1]
As linhas de saída reais são computadas utilizando as expressões de saída do comando SELECT para cada linha selecionada (Consulte a Lista do SELECT abaixo).
Usando os operadores UNION, INTERSECT e EXCEPT podem ser combinadas as saídas de mais de um comando SELECT para formar um único conjunto de resultados. [2] [3] 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 seja especificado ALL (Consulte a Cláusula UNION, a Cláusula INTERSECT e Cláusula EXCEPT abaixo).
Se for especificada a cláusula ORDER BY, as linhas retornadas serão classificadas segundo a ordem especificada. Se a cláusula ORDER BY não for especificada, as linhas serão retornadas na ordem em que o sistema considerar mais rápida de produzir (Consulte a Cláusula ORDER BY abaixo).
A cláusula DISTINCT remove do resultado as linhas duplicadas. [4] [5] 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 (Consulte a Cláusula DISTINCT abaixo).
Se for especificada a cláusula LIMIT ou a cláusula OFFSET, o comando SELECT retornará somente um subconjunto das linhas do resultado (Consulte a Cláusula LIMIT abaixo). [6]
Se for especificada a cláusula FOR UPDATE o comando SELECT bloqueará as linhas selecionadas contra atualizações concorrentes (Consulte a Cláusula FOR UPDATE abaixo). [7]
É 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 forem especificadas várias fontes, 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:
O nome (opcionalmente qualificado pelo esquema) de uma tabela ou de uma visão existente. Se for especificada a cláusula ONLY, somente esta tabela será varrida. Se não for especificada a cláusula ONLY, 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 do parâmetro de configuração sql_inheritance.
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 poderá ser escrita uma lista de aliases de coluna para fornecer nomes substitutos para uma ou mais colunas da tabela.
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.
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.
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).
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.
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 das colunas equivalentes de cada par, e não as duas.
NATURAL é uma forma abreviada para a lista USING fazendo menção a todas as colunas das duas tabelas que possuem o mesmo nome.
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. [8] [9] 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. [10]
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 por uma coluna não agrupada.
A cláusula opcional HAVING possui a forma geral
HAVING condição
onde a 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 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 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 união das linhas retornadas pelos comandos SELECT envolvidos. Uma linha estará 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( portanto, UNION ALL geralmente é significativamente mais rápido do que UNION; deve ser utilizado ALL se for possível).
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. [11] [12]
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 interseção das linhas retornadas pelos comandos SELECT envolvidos. Uma linha estará 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, aparecerá 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).
Atualmente a cláusula FOR UPDATE não pode ser especificada para o resultado do operador INTERSECT, nem em qualquer entrada do operador INTERSECT.
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 aparecerá 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.
Atualmente a cláusula FOR UPDATE não pode ser especificada para o resultado do operador EXCEPT, nem em nenhuma entrada do operador EXCEPT.
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 forem iguais de acordo com a expressão mais à esquerda, estas serã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, serã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 é imprescindível, 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 das cláusulas UNION, INTERSECT ou EXCEPT somente pode especificar nomes de coluna ou números, mas não expressões.
Se a expressão na cláusula ORDER BY for simplesmente um nome correspondendo tanto ao nome de uma coluna do resultado quanto ao nome de uma coluna da entrada, a cláusula ORDER BY interpretará como sendo o nome da coluna do resultado. Esta é a escolha oposta à feita pela cláusula GROUP BY na mesma situação. Esta inconsistência está presente 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 palavras chave 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. [13] [14] [15]
Dados na forma de cadeias de caracteres são classificados de acordo com a ordem de intercalação (collation [16] [17] [18] [19] ) estabelecida quando o agrupamento de bancos de dados foi inicializado.
Se for especificada a cláusula DISTINCT, todas as linhas duplicadas serão removidas do conjunto de resultados (será mantida uma linha para cada grupo de duplicatas). A cláusula ALL especifica o oposto: todas as linhas serã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;
retorna 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 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 seja imposta 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.
A cláusula FOR UPDATE possui a forma
FOR UPDATE [ OF nome_da_tabela [, ...] ]
A cláusula FOR UPDATE faz as linhas retornadas 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 ficarão 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 ficará aguardando a outra transação completar e, então, irá bloquear e retornar a linha atualizada (ou nenhuma linha, se a linha foi excluída). Para obter mais explicações deve ser consultado o Capítulo 12.
Se forem especificados nomes de tabelas na cláusula FOR UPDATE, então somente as linhas vindas destas tabelas serão bloqueadas; todas as outras tabelas usadas no SELECT serão simplesmente lidas como de costume.
FOR UPDATE não pode ser utilizado nos contextos onde as linhas retornadas não podem ser claramente relacionadas 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.id_dist, d.nome, f.data_prod, f.tipo FROM distribuidores d, filmes f WHERE f.id_dist = d.id_dist titulo | id_dist | 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; id_dist | nome ---------+------------------ 109 | 20th Century Fox 110 | Bavaria Atelier 101 | British Lion 107 | Columbia 102 | Jean Luc Godard 113 | Luso films 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: id_dist | 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 id_dist = $1; $$ LANGUAGE SQL; SELECT * FROM distribuidores(111); id_dist | nome ---------+------------- 111 | Walt Disney CREATE FUNCTION distribuidores_2(int) RETURNS SETOF record AS $$ SELECT * FROM distribuidores WHERE id_dist = $1; $$ LANGUAGE SQL; SELECT * FROM distribuidores_2(111) AS (f1 int, f2 text); f1 | f2 -----+------------- 111 | Walt Disney
Junção de colunas com nulos. O próximo exemplo mostra a junção das tabelas t1 e t2 pelas colunas t1.a e t2.c que contêm valores nulos. Como pode ser visto, as linhas das tabelas que contêm o valor nulo na coluna de junção só aparecem nos resultados das consultas quando são utilizadas junções externas, como acontece com as linhas que não possuem valor correspondente na outra tabela, porque os valores nulos não correspondem um ao outro. Abaixo estão mostradas as tabelas t1 e t2, com o hífen representando o valor nulo. [20]
Tabela t1 Tabela t2 +---+---+ +---+---+ | a | b | | c | d | +---+---+ +---+---+ | 1 | 1 | | - | 2 | | - | 2 | | 3 | 3 | | 3 | 3 | | 4 | 4 | +---+---+ +---+---+ (3 linhas) (3 linhas)
Abaixo está mostrado o arquivo join_null.sql utilizado para realizar as junções:
\pset null - \pset border 2 BEGIN; CREATE TEMPORARY TABLE t1 (a int, b int) ON COMMIT DROP; INSERT INTO t1 VALUES (1,1); INSERT INTO t1 VALUES (null,2); INSERT INTO t1 VALUES (3,3); CREATE TEMPORARY TABLE t2 (c int, d int) ON COMMIT DROP; INSERT INTO t2 VALUES (null,2); INSERT INTO t2 VALUES (3,3); INSERT INTO t2 VALUES (4,4); \pset title 'Junção interna' SELECT * FROM t1 JOIN t2 ON t1.a = t2.c ORDER BY t1.a; \pset title 'Junção externa esquerda (t1)' SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.a = t2.c ORDER BY t1.b; \pset title 'Junção externa direita (t2)' SELECT * FROM t1 RIGHT OUTER JOIN t2 ON t1.a = t2.c ORDER BY t2.d; \pset title 'Junção externa completa' SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.a = t2.c ORDER BY t1.b; COMMIT;
A seguir está mostrado o resultado do processamento do arquivo:
# psql -U teste -f join_null.sql -o join_null.out -q teste # cat join_null.out Junção interna +---+---+---+---+ | a | b | c | d | +---+---+---+---+ | 3 | 3 | 3 | 3 | +---+---+---+---+ (1 linha) Junção externa esquerda (t1) +---+---+---+---+ | a | b | c | d | +---+---+---+---+ | 1 | 1 | - | - | | - | 2 | - | - | | 3 | 3 | 3 | 3 | +---+---+---+---+ (3 linhas) Junção externa direita (t2) +---+---+---+---+ | a | b | c | d | +---+---+---+---+ | - | - | - | 2 | | 3 | 3 | 3 | 3 | | - | - | 4 | 4 | +---+---+---+---+ (3 linhas) Junção externa completa +---+---+---+---+ | a | b | c | d | +---+---+---+---+ | 1 | 1 | - | - | | - | 2 | - | - | | 3 | 3 | 3 | 3 | | - | - | 4 | 4 | | - | - | - | 2 | +---+---+---+---+ (5 linhas)
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'; id_dist | 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 desativar 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 das colunas de resultado ou números, 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 são sempre considerados como nomes das colunas da entrada, e não como nomes das colunas do resultado.
O SQL:1999 e posteriores utilizam uma definição um pouco diferente, que não possui total compatibilidade ascendente [21] com o SQL-92. Entretanto, na maioria dos casos o PostgreSQL interpreta uma expressão presente em ORDER BY ou em GROUP BY da mesma maneira que o SQL:1999.
[1] |
SQL Server — A cláusula GROUP BY especifica os grupos onde as linhas de saída deverão ser colocadas. Se existirem funções de agregação na lista de seleção da cláusula SELECT, a cláusula GROUP BY calculará o valor resumido para cada grupo. Quando a cláusula GROUP BY é especificada, ou cada coluna de uma expressão não agregada da lista de seleção deve ser incluída na lista do GROUP BY, ou a expressão do GROUP BY deve corresponder exatamente a expressão da lista de seleção. SQL Server 2005 Books Online — GROUP BY (Transact-SQL) (N. do T.) |
[2] |
SQL Server — conjunto de resultados — (result set) — O conjunto de linhas retornadas pelo comando SELECT. O formato das linhas do conjunto de resultados é definido pela lista de colunas do comando SELECT. SQL Server 2005 Books Online — Glossary of Terms (N. do T.) |
[3] |
DB2 — conjunto de resultados — O conjunto de linhas que um procedimento retorna. Glossário do DB2 (N. do T.) |
[4] |
Oracle — Deve ser especificado DISTINCT ou UNIQUE se for desejado que o banco de dados 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. Não pode ser especificado DISTINCT quando a lista de seleção contém colunas LOB. Oracle® Database SQL Reference 10g Release 1 (10.1) Part Number B10759-01 (N. do T.) |
[5] |
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 2005 Books Online — SELECT Clause (Transact-SQL) (N. do T.) |
[6] |
SQL Server — TOP expressão[ PERCENT ] [ WITH TIES ] indica que somente o primeiro conjunto ou percentagem das linhas especificado será retornado do conjunto de resultados da consulta. A expressão pode ser um número ou a percentagem das linhas. SQL Server 2005 Books Online — SELECT Clause (Transact-SQL) (N. do T.) |
[7] |
Oracle — A cláusula FOR UPDATE permite bloquear as linhas selecionadas, não permitindo assim que outros usuários bloqueiem ou atualizem estas linhas enquanto a transação nã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, a expressão CURSOR, operadores de conjunto, cláusula GROUP BY e funções de agregação. Oracle® Database SQL Reference 10g Release 1 (10.1) Part Number B10759-01 (N. do T.) |
[8] |
SQL Server — O predicado é uma expressão avaliada como TRUE, FALSE ou UNKNOWN. Os predicados são usados nas condições de procura das cláusulas WHERE e HAVING, nas condições de junção das cláusulas FROM, e em outras construções onde é requerido um valor booleano. SQL Server 2005 Books Online — Predicate (Transact-SQL) (N. do T.) |
[9] |
DB2 — O predicado especifica uma condição que é verdadeira, falsa ou desconhecida sobre uma determinada linha ou grupo. DB2 Version 9 for Linux, UNIX, and Windows (N. do T.) |
[10] |
SQL Server — Quando existem valores nulos nas colunas das tabelas sendo juntadas, os valores nulos não correspondem um ao outro. A presença de valores nulos em uma coluna de uma das tabelas sendo juntadas somente pode ser retornado utilizando junções externas (a não ser que a cláusula WHERE exclua os valores nulos). SQL Server 2005 Books Online — Null Values and Joins (N. do T.) |
[11] |
Oracle — Podem ser combinadas várias consultas utilizando os operadores de conjunto UNION, UNION ALL, INTERSECT e MINUS. Todos os operadores de conjunto possuem a mesma precedência. Se o comando SQL tiver vários operadores de conjunto, então o banco de dados Oracle avaliará os operadores da esquerda para a direita, a menos que parênteses especifiquem explicitamente outra ordem. As expressões correspondentes da lista de seleção das consultas componentes da seleção composta devem corresponder em número, e devem ser do mesmo grupo de tipos de dado (como numérico ou caractere). Oracle® Database SQL Reference 10g Release 1 (10.1) Part Number B10759-01 (N. do T.) |
[12] |
SQL Server — O operador UNION combina o resultado de duas ou mais consultas em um único conjunto de resultados que inclui todas as linhas que pertencem a todas as consultas da união. A operação UNION é diferente de utilizar junções que combinam colunas de duas tabelas. A seguir estão as regras básicas para combinar os conjuntos de resultados de duas consultas utilizando UNION: O número e a ordem das colunas deve ser a mesma em todas as consultas; Os tipos de dado devem ser compatíveis. ALL incorpora todas as linhas nos resultados. Isto inclui as duplicadas. Se não for especificado, as linhas duplicadas serão removidas. SQL Server 2005 Books Online — UNION (Transact-SQL) (N. do T.) |
[13] |
Oracle — As cláusulas NULLS FIRST e NULLS LAST especificam se as linhas retornadas contendo valores nulos deverão aparecer no início ou no final na seqüência de ordenação. O padrão é NULLS LAST para a ordem ascendente e NULLS FIRST para a ordem descendente. Oracle® Database SQL Reference 10g Release 1 (10.1) Part Number B10759-01 (N. do T.) |
[14] |
SQL Server — Os valores nulos são tratados como os menores valores possíveis. SQL Server 2005 Books Online — ORDER BY Clause (Transact-SQL) (N. do T.) |
[15] |
DB2 — Os valores nulos são maiores que todos os outros valores. DB2 Version 9 for Linux, UNIX, and Windows (N. do T.) |
[16] |
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.) |
[17] |
SQL Server — intercalação (collation) — é um conjunto de regras que determina como os dados são comparados, ordenados e apresentados. Os dados caractere são classificados de acordo com a informação de intercalação, que inclui o idioma, a ordem de classificação e a diferenciação de letras minúsculas e maiúsculas. SQL Server 2005 Books Online — Glossary of Terms (N. do T.) |
[18] |
collation é uma classificação apropriada para o idioma. Collation (N. do T.) |
[19] |
collation — [informática, computadores] — s. intercalação, f. collation | Portuguese | Dictionary & Translation by Babylon (N. do T.) |
[20] |
Exemplo escrito pelo tradutor, não fazendo parte do manual original. |
[21] |
compatibilidade ascendente (upward compatibility) — característica de um software que funciona sem modificações em versões mais recentes ou mais avançadas de determinado sistema de computador. Webster's New World Dicionário de Informática, Bryan Pfaffenberger, Editora Campus, 1999, pág. 200. (N. do T.) |