sql >> Base de Datos >  >> RDS >> Database

Cómo escribir consultas complejas en SQL

Las consultas típicas en el formato de tabla SELECT * FROM a veces no son suficientes. Cuando los datos de una consulta no están en una tabla, sino en varias, o cuando es necesario especificar varios parámetros de selección a la vez, necesitará consultas más sofisticadas.

Este artículo explicará cómo crear tales consultas y brindará ejemplos de consultas SQL complejas.

¿Qué aspecto tiene una consulta compleja?

Primero, definamos las condiciones para componer la consulta SQL. En particular, deberá utilizar los siguientes parámetros de selección:

  • los nombres de las tablas de las que desea extraer datos;
  • los valores de los campos que deben devolverse a los originales después de realizar cambios en la base de datos;
  • las relaciones entre tablas;
  • las condiciones de muestreo;
  • los criterios auxiliares de selección (restricciones, formas de presentar la información, tipo de clasificación).

Para comprender mejor el tema, consideremos un ejemplo que utiliza las siguientes cuatro tablas simples. La primera línea es el nombre de la tabla que en consultas complejas actúa como clave externa. Consideraremos esto en detalle con un ejemplo:

Cada tabla tiene filas relacionadas con otras tablas. Explicaremos por qué es necesario más adelante.

Ahora, veamos la consulta SQL básica:

SELECT * FROM companies WHERE companies_name %STARTSWITH 'P';

El %COMIENZA CON el predicado selecciona filas que comienzan con el carácter/los caracteres especificados.

El resultado se ve así:

Ahora, consideremos una consulta SQL compleja:

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;

El resultado es la siguiente tabla:

La tabla muestra las empresas, el número correspondiente de llamadas telefónicas y su duración aproximada.

Además, enumera solo los nombres de las empresas en las que la duración media de las llamadas es mayor que la duración media de las llamadas en otras empresas.

¿Cuáles son las reglas principales para crear consultas SQL complejas?

Intentemos crear un algoritmo multipropósito para componer consultas complejas.

En primer lugar, debe decidir las tablas que constan de los datos que forman parte de la consulta.

El ejemplo anterior involucra a las empresas y llamadas mesas. Si las tablas con los datos requeridos no están directamente relacionadas entre sí, también debe incluir las tablas intermedias que las unen.

Por eso también conectamos mesas, como oficinas y clientes , utilizando claves foráneas. Por lo tanto, cualquier resultado de la consulta con tablas de este ejemplo siempre incluirá las siguientes líneas:

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;

Una tabla combinada sugiere los tres puntos más importantes:

  • Preste atención a la lista de campos después de SELECCIONAR. La operación de lectura de datos de tablas unidas requiere que especifique el nombre de la tabla que se unirá en el nombre campo.
  • Su consulta compleja siempre tendrá la tabla principal (empresas ). La mayoría de los campos se leen de él. La tabla adjunta, en nuestro ejemplo, utiliza tres tablas:oficinas , clientes y llamadas . El nombre se determina después del operador JOIN.
  • Además de especificar el nombre de la segunda tabla, asegúrese de especificar la condición para realizar la combinación. Hablaremos más sobre esta condición.
  • La consulta mostrará una tabla con una gran cantidad de filas. No es necesario publicarlo aquí, ya que muestra resultados intermedios. Sin embargo, siempre puede verificar su salida usted mismo. Esto es muy importante, ya que ayuda a evitar errores en el resultado final.

Ahora veamos la parte de la consulta que compara la duración de las llamadas dentro de cada empresa y entre todas las empresas. Necesitamos calcular la duración promedio de todas las llamadas. Utilice la siguiente consulta:

SELECT AVG(DATEDIFF(SECOND, calls.start_time, calls.end_time)) FROM calls

Tenga en cuenta que usamos el DATEDIFF función que genera la diferencia entre los períodos especificados. En nuestro caso, la duración media de la llamada es igual a 335 segundos.

Ahora agreguemos datos sobre llamadas de todas las empresas a la 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;

En esta consulta,

  • SUMA (CASO CUANDO llamadas.id NO ES NULO ENTONCES 1 OTRO 0 FIN) – para evitar operaciones innecesarias, resumimos solo las llamadas existentes – cuando el número de llamadas en una empresa no es cero. Esto es muy importante en tablas grandes con posibles valores nulos.
  • PROMEDIO (ESNULL (DATEDIFF (SEGUNDO, llamadas.start_time, llamadas.end_time), 0)) – la consulta es idéntica a la consulta AVG anterior. Sin embargo, aquí usamos el ISNULL operador que reemplaza NULL con 0. Es necesario para empresas sin llamadas.

Nuestros resultados:

Casi terminamos. La tabla anterior presenta la lista de empresas, el número correspondiente de llamadas para cada una de ellas y la duración promedio de las llamadas en cada una de ellas.

Solo queda comparar los números de la última columna con la duración promedio de todas las llamadas de todas las compañías (335 segundos).

Si ingresa la consulta que presentamos al principio, solo agregue el HAVING parte, obtendrás lo que necesitas.

Recomendamos enfáticamente agregar comentarios en cada línea para que no se confunda en el futuro cuando necesite corregir algunas consultas SQL complejas existentes.

Reflexiones finales

Aunque cada consulta SQL compleja requiere un enfoque individual, algunas recomendaciones son adecuadas para la preparación de la mayoría de estas consultas.

  • determinar qué tablas participarán en la consulta;
  • crear consultas complejas a partir de partes más simples;
  • verificar la precisión de las consultas secuencialmente, en partes;
  • probar la precisión de su consulta con tablas más pequeñas;
  • escriba comentarios detallados en cada línea que contenga el operando, usando los símbolos '-'.

Las herramientas especializadas hacen que este trabajo sea mucho más sencillo. Entre ellos, recomendamos usar Query Builder, una herramienta visual que permite construir incluso las consultas más complejas mucho más rápido en un modo visual. Esta herramienta está disponible como una solución independiente o como parte de dbForge Studio para SQL Server con funciones múltiples.

Esperamos que este artículo te haya ayudado a aclarar este tema específico.