Database
 sql >> Base de Dados >  >> RDS >> Database

Como escrever consultas complexas em SQL


As consultas típicas no formato de tabela SELECT * FROM às vezes não são suficientes. Quando os dados de uma consulta não estiverem em uma tabela, mas em várias, ou quando for necessário especificar vários parâmetros de seleção de uma só vez, você precisará de consultas mais sofisticadas.

Este artigo explicará como criar essas consultas e fornecerá exemplos de consultas SQL complexas.

Como é uma consulta complexa?


Primeiro, vamos definir as condições para compor a consulta SQL. Em particular, você precisará usar os seguintes parâmetros de seleção:
  • os nomes das tabelas das quais você deseja extrair dados;
  • os valores dos campos que devem ser devolvidos aos originais após fazer alterações no banco de dados;
  • as relações entre tabelas;
  • as condições de amostragem;
  • os critérios auxiliares de seleção (restrições, formas de apresentação das informações, tipo de classificação).

Para entender melhor o tópico, vamos considerar um exemplo que usa as quatro tabelas simples a seguir. A primeira linha é o nome da tabela que em consultas complexas atua como chave estrangeira. Vamos considerar isso mais detalhadamente com um exemplo:

Cada tabela tem linhas relacionadas a algumas outras tabelas. Vamos explicar por que é necessário mais adiante.

Agora, vamos ver a consulta SQL básica:
SELECT * FROM companies WHERE companies_name %STARTSWITH 'P';

O %STARTSWITH predicate seleciona linhas que começam com o caractere/caracteres especificados.

O resultado fica assim:

Agora, vamos considerar uma consulta SQL complexa:
SELECT 
	companies.companies_name,
	SUM(CASE WHEN call.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
	AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) AS avgdifference
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
GROUP BY 
	companies.id,
	companies.companies_name
HAVING AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) > (SELECT AVG(DATEDIFF(SECOND, calls.start_time, calls.end_time)) FROM calls)
ORDER BY calls DESC, companies.id ASC;

O resultado é a seguinte tabela:

A tabela mostra as empresas, o número correspondente de chamadas telefônicas e sua duração aproximada.

Além disso, ele lista apenas os nomes de empresas em que a duração média das chamadas é maior do que a duração média das chamadas em outras empresas.

Quais são as principais regras para criar uma consulta SQL complexa?


Vamos tentar criar um algoritmo multiuso para compor consultas complexas.

Antes de tudo, você precisa decidir sobre as tabelas que consistem nos dados que participam da consulta.

O exemplo acima envolve as empresas e chamadas mesas. Se as tabelas com os dados necessários não estiverem diretamente relacionadas umas às outras, você também precisará incluir as tabelas intermediárias que as unem.

Por esse motivo, também conectamos tabelas, como escritórios e clientes , usando chaves estrangeiras. Portanto, qualquer resultado da consulta com as tabelas deste exemplo sempre incluirá as linhas abaixo:
SELECT 
	...
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
...;

After that, you must test the correctness of the behavior in the following part of the query:

SELECT * FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id;

Uma tabela combinada sugere os três pontos mais importantes:
  • Preste atenção à lista de campos após SELECT. A operação de leitura de dados de tabelas unidas requer que você especifique o nome da tabela a ser unida no nome campo.
  • Sua consulta complexa sempre terá a tabela principal (empresas ). A maioria dos campos são lidos a partir dele. A tabela anexada, em nosso exemplo, usa três tabelas – escritórios , clientes , e chamadas . O nome é determinado após o operador JOIN.
  • Além de especificar o nome da segunda tabela, certifique-se de especificar a condição para realizar a junção. Discutiremos essa condição mais detalhadamente.
  • A consulta exibirá uma tabela com um grande número de linhas. Não há necessidade de publicá-lo aqui, pois apresenta resultados intermediários. No entanto, você sempre pode verificar sua saída por conta própria. Isso é muito importante, pois ajuda a evitar erros no resultado final.

Agora vamos ver a parte da consulta que compara as durações das chamadas dentro de cada empresa e entre todas as empresas. Precisamos calcular a duração média de todas as chamadas. Use a seguinte consulta:
SELECT AVG(DATEDIFF(SECOND, calls.start_time, calls.end_time)) FROM calls

Observe que usamos o DATEDIFF função que gera a diferença entre os períodos especificados. No nosso caso, a duração média da chamada é igual a 335 segundos.

Agora vamos adicionar dados de chamadas de todas as empresas à consulta.
SELECT 
	companies.companies_name,
	SUM(CASE WHEN calls.id IS NOT NULL THEN 1 ELSE 0 END) AS calls,
	AVG(ISNULL(DATEDIFF(SECOND, calls.start_time, calls.end_time),0)) AS avgdifference
FROM companies 
LEFT JOIN offices ON offices.companies_id = companies.id
LEFT JOIN customers ON offices.id = customers.offices_id
LEFT JOIN calls ON calls.customers_id = customers.id
GROUP BY 
	companies.id,
	companies.companies_name
ORDER BY calls DESC, companies.id ASC;

Nesta consulta,
  • SOMA (CASO QUANDO Calls.id NÃO É NULL THEN 1 ELSE 0 END) – para evitar operações desnecessárias, resumimos apenas as chamadas existentes – quando o número de chamadas em uma empresa não é zero. Isso é muito importante em tabelas grandes com possíveis valores nulos.
  • AVG (ISNULL (DATEDIFF (SECOND, calls.start_time, calls.end_time), 0)) – a consulta é idêntica à consulta do AVG acima. No entanto, aqui usamos o ISNULL operador que substitui NULL por 0. É necessário para empresas sem chamadas.

Nossos resultados:

Estamos quase terminando. A tabela acima apresenta a lista de empresas, o número correspondente de chamadas para cada uma delas e a duração média das chamadas em cada uma delas.

Resta comparar os números da última coluna com a duração média de todas as ligações de todas as empresas (335 segundos).

Se você inserir a consulta que apresentamos no início, basta adicionar o HAVING parte, você terá o que precisa.

É altamente recomendável adicionar comentários em cada linha para que você não fique confuso no futuro quando precisar corrigir algumas consultas SQL complexas existentes.

Considerações finais


Embora cada consulta SQL complexa exija uma abordagem individual, algumas recomendações são adequadas para a preparação da maioria dessas consultas.
  • determinar quais tabelas participarão da consulta;
  • criar consultas complexas a partir de partes mais simples;
  • verifique a precisão das consultas sequencialmente, em partes;
  • teste a precisão de sua consulta com tabelas menores;
  • escreva comentários detalhados em cada linha que contém o operando, usando os símbolos '-'.

Ferramentas especializadas tornam este trabalho muito mais simples. Entre eles, recomendamos o uso do Query Builder – uma ferramenta visual que permite construir até as consultas mais complexas muito mais rapidamente em modo visual. Essa ferramenta está disponível como uma solução autônoma ou como parte do dbForge Studio para SQL Server com vários recursos.

Esperamos que este artigo tenha ajudado você a esclarecer esse problema específico.