PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Cláusulas de Atenção:Tudo sobre SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY e LIMIT


SQL é uma linguagem de bancos de dados e PostgreSQL é a nossa escolhida. Muitas vezes, armazenar dados é apenas uma faceta do processo. Normalmente, em qualquer empreendimento centrado em dados, você irá:visualizar e ler dados, agir ou implementar mudanças nos dados, coletar informações de tomada de decisão (análises) ou manipular os dados armazenados de alguma forma.

SQL é composto de uma combinação de palavras-chave, comandos e cláusulas. SQL parece simples. Apenas alguns 'fáceis ' comandos aqui e ali. Não é grande coisa, certo?

Mas, há mais no SQL do que aparenta. O SQL pode te enganar naqueles 'fáceis ' consultas.

Um desafio (que devo revisitar rotineiramente) é entender que a ordem de execução do SQL é definitivamente diferente daquela de sua sintaxe.

Nesta postagem do blog, visito, em alto nível, as principais cláusulas SQL aplicadas ao PostgreSQL. Existem muitos dialetos de SQL, mas a interpretação do PostgreSQL é o foco aqui. (Algumas características de cada cláusula podem se aplicar a outros dialetos SQL.)

As cláusulas SQL formam a base para comandos e consultas básicos e frequentemente usados. Dito isto, consultas e exemplos avançados utilizando funções de janela, CTEs, tabelas derivadas, etc., não serão abordados neste post.

Como veremos, nem todas as cláusulas são criadas iguais. No entanto, eles operam em conjunto, fornecendo resultados de consulta perfeitamente (ou não).

Permita-me esclarecer...

Periodicamente, farei menção a uma ordem de execução ao longo da postagem do blog, pois ela se aplica a muitas das cláusulas. Mas, isso é generalizado.

No meu entendimento, na maioria das vezes, o otimizador escolhe e decide o melhor plano de consulta para execução.

SELECT - A cláusula 'picky' usada para consultar o banco de dados


SELECT é uma cláusula ocupada. Está em todo lugar. Usado mais do que todas as outras cláusulas. Certas cláusulas que você pode não precisar. Não é tanto o caso de SELECT, pois é uma cláusula obrigatória.

A cláusula SELECT normalmente é usada para consultar o banco de dados, contendo (em um nível básico):
  1. Uma lista SELECT - As colunas de dados que você deseja.
  2. os conjuntos de dados de origem - nomeados na cláusula FROM. Tabelas, visualizações, CTEs, etc. É daí que vêm os dados.
  3. uma cláusula WHERE opcional usada para filtrar linhas fornecidas pela cláusula FROM.

(As cláusulas FROM e WHERE serão discutidas em suas respectivas seções.)

Na verdade, eu diria que a cláusula SELECT é necessária no PostgreSQL para recuperar qualquer coisa. Mas então, existe o comando TABLE que retorna todas as linhas e colunas de uma tabela.

No entanto, há uma separação entre os dois. SELECT pode especificar colunas individuais, mas com o comando TABLE, todas as colunas são retornadas.

SELECIONE destaques:
  • SELECT * é uma notação abreviada e retorna todas as colunas das fontes de dados.
  • Embora SELECT seja nomeado em termos de sintaxe como a primeira cláusula (com exceção daquelas consultas usando uma cláusula WITH:não discutida aqui), ele não é executado primeiro. Notavelmente, SELECT também não é a última cláusula a ser executada.
  • Uma expressão (ou qualquer coluna) pode receber um nome de referência ou ALIAS na cláusula SELECT, com uma ressalva. Esses nomes podem ser usados ​​nas cláusulas ORDER BY e GROUP BY, mas não nas cláusulas WHERE ou HAVING.
  • Quando uma cláusula GROUP BY está presente (ou funções agregadas) na consulta, SELECT não deve nomear nenhuma(s) coluna(s) desagrupada(s). Apenas as colunas em qualquer função agregada ou aquelas funcionalmente dependentes das colunas agrupadas.
  • O SELECT não apenas retorna colunas específicas, mas seu uso também se estende às instruções INSERT e CREATE TABLE.
  • A cláusula SELECT está longe de ser simples.

Consulte a seção de documentação oficial da cláusula SELECT do PostgreSQL para obter uma cobertura detalhada.

FROM - Fornece a(s) fonte(s) de dados para a consulta


FROM é principalmente uma cláusula obrigatória. Eu chamo isso de 'vagamente ' por causa do comando TABLE disponível (mencionado acima), que não requer a cláusula FROM.

Então, novamente, você pode selecionar expressões arbitrárias, sem nenhuma tabela nomeada em uma consulta SELECT. No entanto, com TABLE, isso não é possível.

Aqui está um exemplo no psql:
learning=> SELECT 2+2;
?column? 
----------
4
(1 row)

Mas com TABELA:
learning=> TABLE 2+2;
ERROR: syntax error at or near "2"
LINE 1: TABLE 2+2;
^

Alguns dialetos SQL permitem até mesmo nomear uma tabela inexistente para mitigar não ter uma tabela real na cláusula FROM. No entanto, no PostgreSQL, como você pode ver na consulta simples acima, isso não é obrigatório.

Mas, se você precisar de dados armazenados reais retornados além de expressões simples, precisará da cláusula FROM. Sem ele, não há dados para operar.

Portanto, FROM é absolutamente necessário para consultar quaisquer tabelas.

No Postgres, todas as tabelas nomeadas na cláusula FROM são primeiramente cruzadas (se uma cláusula WITH não estiver presente) na ordem de execução que estabelece um Produto Cartesiano. Isso faz sentido, pois precisamos de dados para trabalhar.

A documentação FROM aqui também observa que, normalmente, esse conjunto de dados é reduzido a um pequeno número de linhas por meio de uma condição de cláusula WHERE presente.

A cláusula FROM aceita vários elementos específicos. Aqui estão apenas alguns (consulte a documentação de links abaixo para obter a lista completa):
  • Nome da tabela (obviamente precisamos disso).
  • UMA VISUALIZAÇÃO.
  • Uma instrução SELECT (uma subconsulta).
  • Nome CTE (cláusula COM).
  • Tipo de JOIN - se houver.
  • Uma função (eu não sabia disso. Que legal!!!)

DOS destaques:
  • Embora FROM seja listado sintaticamente como a segunda cláusula em uma consulta SELECT, ela é executada primeiro.
  • FROM fornece (ao carregar) todas as linhas de quaisquer tabelas (reais ou virtuais) nomeadas em sua cláusula.
  • Os nomes das tabelas podem ter um alias na cláusula FROM (por exemplo, FROM shoe AS s), mas precisam ser referenciados por esse ALIAS durante toda a consulta.
  • FROM é uma cláusula obrigatória ao consultar tabelas.

Veja a seção da cláusula Official PostgreSQL FROM para uma cobertura detalhada.

WHERE - Filtra as linhas das fontes de dados com base nas expressões condicionais de validação booleana


WHERE é uma cláusula opcional. Ainda, quando presente em uma consulta, seu dever é remover aqueles registros fornecidos pela cláusula FROM que não passam em sua verificação condicional booleana.

A cláusula WHERE também tem uso profundo com outros comandos SQL além do SELECT. Ou seja, comandos DML como INSERT (não diretamente, mas via SELECT), UPDATE e DELETE.

De fato, sem uma cláusula WHERE, as instruções UPDATE e DELETE provavelmente afetariam todas as linhas de destino. Talvez não o que você pretendia (Caramba!).

As funções agregadas não podem ser usadas na expressão condicional booleana da cláusula WHERE. Nenhum agrupamento ainda aconteceu na ordem de execução. Portanto, os agregados não estão disponíveis (ainda) para a cláusula WHERE.

A avaliação WHERE é baseada em uma verificação booleana usando qualquer um dos operadores de comparação. (Por exemplo,>, <, =, <>, etc...)

A cláusula WHERE não pode acessar nomes de coluna com alias listados na cláusula SELECT. Como a cláusula SELECT é realmente (sem sintaxe) executado após a cláusula WHERE, essas colunas com alias ainda não estão disponíveis.

ONDE destaques:
  • As funções agregadas não são acessíveis e não podem ser usadas na verificação condicional booleana de uma cláusula WHERE. (A cláusula WHERE é possivelmente responsável por quaisquer linhas fornecidas para agregar funções e agrupamento para cálculo.)
  • Colunas com alias na cláusula SELECT não podem ser referenciadas na cláusula WHERE.
  • A verificação condicional da expressão booleana da cláusula WHERE pode resultar em:verdadeiro, falso ou NULL.
  • Todas as linhas nas quais a expressão booleana da cláusula WHERE é avaliada como falsa ou NULL são removidas.
  • Várias condições booleanas podem ser verificadas na cláusula WHERE aproveitando as palavras-chave AND ou OR.

Veja a seção da cláusula Official PostgreSQL WHERE para uma cobertura detalhada.

GROUP BY - Grupos de formulários


É uma cláusula opcional.

Esta cláusula cria uma única linha para os selecionados, que contém uma correspondência no valor da coluna agrupada especificada.

GROUP BY pode ser complicado, portanto, acho pertinente incluir esta passagem da documentação:

"Quando GROUP BY está presente, ou quaisquer funções agregadas estão presentes, não é válido para as expressões de lista SELECT se referirem a colunas desagrupadas, exceto dentro de funções agregadas ou quando a coluna desagrupada é funcionalmente dependente das colunas agrupadas, pois de outra forma haveria mais de um valor possível para retornar para uma coluna desagrupada. Existe uma dependência funcional se as colunas agrupadas (ou um subconjunto delas) forem a chave primária da tabela que contém a coluna desagrupada."

GRUPO POR destaques:
  • O Postgres permite o agrupamento não apenas de colunas da tabela de origem, mas também das listadas na lista de colunas SELECT. Isso é um pouco diferente do SQL estrito.
  • Em determinadas consultas, GROUP BY pode imitar a cláusula DISTINCT removendo valores duplicados da coluna da cláusula SELECT.
  • A ordem das colunas é irrelevante para GROUP BY.
  • Essas colunas não segmentadas pela cláusula GROUP BY não podem ser referenciadas, exceto em agregados.
  • Em muitos casos, você pode agrupar em uma PRIMARY KEY para as colunas funcionalmente dependentes dessa chave.
  • O agrupamento ainda é realizado para consultas que utilizam funções agregadas na ausência de uma cláusula GROUP BY.

Veja a seção da cláusula Official PostgreSQL GROUP BY para uma cobertura detalhada.

HAVING - Filtra GROUP BY Column(s) e funções agregadas


É uma cláusula opcional.

HAVING filtra as linhas do conjunto de resultados com uma verificação condicional booleana assim como a cláusula WHERE, exceto que filtra as linhas formadas pela cláusula GROUP BY e/ou funções agregadas.

TENDO destaques:
  • A cláusula HAVING pode fazer referência às colunas nomeadas em funções agregadas (mesmo aquelas não agrupadas), além de quaisquer colunas GROUP BY.
  • HAVING é responsável por eliminar linhas após a aplicação de funções agregadas ou agrupamento.
  • Você pode fazer referência a colunas não agregadas na cláusula HAVING, embora isso tenha muito pouco uso.
  • Embora a cláusula HAVING seja muitas vezes usada em conjunto com a cláusula GROUP BY, você pode usá-la sozinha. Os resultados da consulta são formados em um único grupo dessas colunas apenas em funções agregadas.

Consulte a seção Cláusula oficial do PostgreSQL HAVING para obter uma cobertura detalhada.

ORDER BY - Uma medida de ordem fora da aleatoriedade


É uma cláusula opcional.

Use ORDER BY quando precisar de um pedido específico. Caso contrário, o banco de dados pode (e irá) retornar resultados em qualquer ordenação arbitrária.

Mesmo que os resultados pareçam estar em alguma ordem, isso não é garantido.

Não se engane. Utilize ORDEM POR.

Existem dois padrões de pedidos disponíveis. Ordem ASC (ascendente) ou DESC (descendente), sendo ASC o padrão.

Se seu conjunto de resultados incluir valores NULL, eles também podem ser usados ​​na ordenação da seguinte forma:especificar NULLS LAST faz com que eles (NULLs) sejam classificados após não NULLs, enquanto solicitar NULLS FIRST é o inverso.

ORDEM POR destaques:
  • Expressão(ões) de classificação são aquelas que seriam permitidas na lista SELECT da consulta.
  • O PostgreSQL permite ORDER BY colunas não presentes na cláusula SELECT onde alguns dialetos SQL não.
  • Os resultados da consulta são caprichosos e não garantem que se pareçam com qualquer padrão ou ordem, a menos que uma cláusula ORDER BY seja usada.
  • ORDER BY e a cláusula LIMIT (veja a próxima seção) são ótimas combinadas para determinar um 'Top ' conjunto de resultados de linhas. (por exemplo, 5 dias de maior venda, 5 pares de sapatos mais vendidos, melhor vendedor neste trimestre)
  • Você pode ordenar os resultados por número de posição da coluna na lista SELECT, mas o número especificado não deve ser maior que o número de itens na lista de cláusulas SELECT. Em outras palavras, se a cláusula SELECT tiver apenas 2 itens, ORDER BY 3 produzirá um erro.
  • Cada expressão individual é ordenada apenas por sua opção listada. (por exemplo, ORDER BY col_1 DESC, col_2 DESC não é o mesmo que ORDER BY col_1, col_2 DESC)

Veja a seção da cláusula Official PostgreSQL ORDER BY para uma cobertura detalhada.
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper

LIMIT - Recuperar um número específico de linhas dos resultados da consulta


LIMIT é uma cláusula opcional.

LIMIT na verdade consiste em 2 subcláusulas, sendo OFFSET a segunda delas.

Se um valor for fornecido para a parte OFFSET da cláusula, as linhas do conjunto de resultados serão retornadas depois pulando esse número de linhas.

Uma seção importante na documentação a ser observada:

"O planejador de consulta leva em consideração LIMIT ao gerar um plano de consulta, portanto, é muito provável que você obtenha planos diferentes (produzindo ordens de linha diferentes) dependendo do que você usa para LIMIT e OFFSET. Assim, usando valores diferentes de LIMIT/OFFSET para selecionar diferentes os subconjuntos de um resultado de consulta fornecerão resultados inconsistentes, a menos que você imponha uma ordenação de resultado previsível com ORDER BY. Isso não é um bug; é uma consequência inerente do fato de que o SQL não promete entregar os resultados de uma consulta em nenhuma ordem específica a menos que ORDER BY seja usado para restringir o pedido."

LIMIT destaques:
  • LIMIT pode retornar menos linhas do que o número definido se a própria consulta produzir menos linhas no conjunto de resultados. Em outras palavras, não teria impacto no número de linhas retornadas.
  • A sintaxe LIMIT ALL é aceitável e tem o mesmo efeito de não incluir uma cláusula LIMIT.
  • Embora o número 'x' de linhas seja ignorado devido a uma cláusula OFFSET, esta não é uma 'solução alternativa ' para qualquer ganho de desempenho, pois eles ainda são calculados para o plano de consulta no servidor.
  • OFFSET 0 é equivalente a não incluir uma cláusula OFFSET.

Veja a seção Official PostgreSQL LIMIT Clause para uma cobertura detalhada.

A interpretação do PostgreSQL das principais cláusulas SQL é própria. Independentemente de como o PostgreSQL opte por implementá-los ou não, eles são fundamentais para consultas SQL e a familiaridade com suas características individuais (e nuances) só pode beneficiar os usuários no futuro.

Embora volumes de artigos, livros, documentação e postagens de blog tenham sido escritos em cada uma dessas cláusulas, espero que você ache esta visão geral de alto nível digerível e informativa.

Obrigado por ler.