Me resulta muy difícil escribir consultas SQL complejas que involucren uniones en muchas tablas (al menos 3-4) e involucren varias condiciones anidadas. Las consultas que se me pide que escriba se describen fácilmente con unas pocas oraciones, pero pueden requerir una cantidad engañosa de código para completar. Me encuentro a menudo usando vistas temporales para escribir estas consultas, que parecen un poco muletas. ¿Qué consejos me puede proporcionar que pueda utilizar para facilitar estas consultas complejas? Más específicamente, ¿cómo divido estas consultas en los pasos que necesito usar para escribir realmente el código SQL?
Tenga en cuenta que soy el SQL que se me pide que escriba es parte de las tareas para un curso de base de datos, por lo que no quiero un software que haga el trabajo por mí. Quiero entender realmente el código que estoy escribiendo.
Más detalles técnicos:
- La base de datos está alojada en un servidor PostgreSQL que se ejecuta en la máquina local.
- La base de datos es muy pequeña: no hay más de siete tablas y la tabla más grande tiene menos de aproximadamente 50 filas.
- Las consultas SQL se pasan sin modificaciones al servidor, a través de LibreOffice Base.
Respuestas:
Estoy basando la mayor parte de esto en tratar de obtener la respuesta "correcta", por lo que puede descubrir que hay algunos problemas de rendimiento. No tiene sentido acelerar una consulta incorrecta.
Comprenda las relaciones de la tabla : la mayoría será de una a muchas. Conozca la tabla "muchos". Identifique los campos requeridos para sus uniones.
Piense en los escenarios de unión IZQUIERDA : seleccione todos los empleados y su cheque de pago del mes pasado. ¿Qué pasa si no recibieron un cheque de pago el mes pasado?
Conozca el conjunto de resultados: 1) En una hoja de cálculo, ingrese manualmente al menos un registro correcto para su consulta. 2) Escriba la consulta de forma suficientemente simple para identificar cuántos registros deben devolverse. Use ambos para probar su consulta y asegurarse de que unirse a una nueva tabla no altere el resultado.
Divida su consulta en partes manejables : no tiene que escribirla de una vez. Las consultas complejas a veces pueden ser solo una colección de consultas simples.
Tenga cuidado con los niveles mixtos de agregación : si tiene que poner valores mensuales, trimestrales y anuales hasta la fecha en el mismo conjunto de resultados, deberá calcularlos por separado en consultas agrupadas en diferentes valores.
Sepa cuándo UNIR A veces es más fácil dividir los subgrupos en sus propias declaraciones de selección. Si tiene una tabla mezclada con gerentes y otros empleados, y en cada columna debe hacer declaraciones de casos basadas en la membresía en uno de estos grupos, puede ser más fácil escribir una consulta de Gerente y unir a una consulta de Empleado. Cada uno contendría su propia lógica. Tener que incluir elementos de diferentes tablas en diferentes filas es un uso obvio.
Fórmulas complejas / anidadas : intente sangrar constantemente y no tenga miedo de usar varias líneas. "CASO CUANDO CASO CUANDO CASO CUANDO" te volverá loco. Tómese el tiempo para pensar en esto. Guarde los cálculos complejos para el final. Obtenga los registros correctos seleccionados primero. Luego atacas fórmulas complejas sabiendo que estás trabajando con los valores correctos. Ver los valores utilizados en las fórmulas lo ayudará a detectar áreas donde debe tener en cuenta los valores NULL y dónde manejar el error de división por cero.
Pruebe a menudo a medida que agrega nuevas tablas para asegurarse de que todavía obtiene el conjunto de resultados deseado y sabe qué unión o cláusula es la culpable.
fuente
La sangría sería lo primero que debería hacer, si aún no lo está haciendo. No solo es útil incluso con consultas simples, sino que es crucial cuando se trata de uniones y consultas un poco más complejas que a
select top 1 [ColumnName] from [TableName]
.Una vez sangrado correctamente, nada prohíbe agregar comentarios dentro de la consulta, cuando sea apropiado. No los use en exceso: si el código es lo suficientemente explícito, agregar comentarios solo dañará la claridad del código. Pero todavía son bienvenidos para las partes menos explícitas de la consulta.
Tenga en cuenta que las consultas más largas (incluidas las consultas con comentarios) significarían un mayor uso de ancho de banda entre su servidor de aplicaciones y su servidor de base de datos. También tenga en cuenta que a menos que esté trabajando en un producto a escala de Google con una gran cantidad de solicitudes por segundo, que requiera un rendimiento excepcional y un uso de recursos, el tamaño agregado por los comentarios puede no cambiar nada para usted en términos de rendimiento.
Aplicar el mismo estilo sobre tablas, columnas, etc. también ayuda mucho a la legibilidad. Cuando una base de datos existente tiene las tablas
PRODUCT
,users
,USERS_ObsoleteDONT_USE
,PR_SHIPMENTS
yHRhbYd_UU
, alguien está haciendo algo muy malo.Aplicar el mismo estilo sobre las consultas también es importante. Por ejemplo, si está escribiendo consultas para Microsoft SQL Server y decidió usarlas en
[TableName]
lugar de hacerloTableName
, quédese con ellas. Si va a una nueva línea después de unselect
, no lo haga solo en la mitad de sus consultas, sino en todas.No lo use
*
, a menos que haya razones sólidas para hacerlo (comoif exists(select * from [TableName] where ...)
en Microsoft SQL Server). No solo*
tiene un impacto negativo en el rendimiento en algunas (si no la mayoría) de las bases de datos, sino que tampoco es útil para el desarrollador que utiliza su consulta. Del mismo modo, un desarrollador debe acceder a los valores por nombre, nunca por índice.Finalmente, para las selecciones, no hay nada de malo en proporcionar una vista . Para cualquier otra cosa, los procedimientos almacenados también pueden usarse según el proyecto y las personas con las que está trabajando².
¹ Algunas personas odian los procedimientos almacenados. A otros no les gustan por varias razones (perfectamente válidas, al menos por ellas).
² Tus colegas, los otros estudiantes, tu profesor, etc.
fuente
Aquí hay un poco de oscuridad, pero si está escribiendo muchas vistas temporales, quizás aún no se haya dado cuenta de que en la mayoría de los lugares donde podría colocar una tabla en una declaración SQL, esa tabla puede reemplazarse por una consulta.
Entonces, en lugar de unir la tabla A a la vista temporal B, puede unir la tabla A a la consulta que ha estado utilizando como vista temporal B. Por ejemplo:
Este ejemplo no tiene sentido, pero debería explicar la sintaxis.
Para las vistas que no son "especiales" (indexadas, particionadas), esto debería dar como resultado el mismo plan de consulta que si utilizara una vista.
En cuanto a facilitar la escritura, puede verificar cada pieza para asegurarse de obtener lo que espera antes de escribir toda la consulta.
Mis disculpas si esto ya es viejo para ti.
fuente
En lugar de vistas temporales, use la cláusula WITH . Esto hace que sea mucho más fácil dividir las consultas grandes en partes más pequeñas más legibles.
fuente
fuente
Como cualquier otra cosa, desea dividir el problema en partes manejables.
Por cierto, así es como resuelves problemas complejos.
Entonces: desea consultar la subconsulta para ver que realmente devuelve lo que desea antes de ejecutar una consulta externa. Desea probar una combinación mínima de cada tabla en la que se está uniendo para poder ver que realmente está pensando bien. Ese tipo de cosas. Esperar escribirlo todo y sacar exactamente lo que quieres de un golpe no es realista.
Una declaración SQL, una vez que alcanza un cierto nivel de complejidad, es básicamente un pequeño programa en sí mismo. Hace una gran diferencia comprender realmente cómo se combinan, seleccionan, filtran y generan los datos.
fuente