2011-03-28 9 views
26

Estoy escribiendo algunas consultas SQL con varias subconsultas y muchas combinaciones en todas partes, tanto en la subconsulta como en la tabla resultante de la subconsulta.Formateo de consultas SQL claras y legibles

No estamos utilizando vistas, por lo que está fuera de cuestión.

Después de escribirlo lo estoy mirando y me rasco la cabeza preguntándome qué está haciendo porque no puedo seguirlo.

¿Qué tipo de formato utilizas para intentar limpiar ese desorden? ¿Sangría quizás?

+0

¿qué plataforma? Hay complementos para SSMS y MySQL Workbench que "embellecerán" su código SQL por usted. –

+0

Buena pregunta. Aún no he encontrado una regla de formato convincente para SQL. –

+0

@Brian Driscoll, ¿qué plugings conoces para MySQL Workbench? – dcarneiro

Respuesta

17

Con grandes consultas tiendo a depender mucho de conjuntos de resultados nombrados usando WITH. Esto permite definir el conjunto de resultados de antemano y simplifica la consulta principal. Los conjuntos de resultados nombrados pueden ayudar a que el plan de consulta sea más eficiente también, como p.postgres almacena el conjunto de resultados en una tabla temporal.

Ejemplo:

WITH 
    cubed_data AS (
    SELECT 
     dimension1_id, 
     dimension2_id, 
     dimension3_id, 
     measure_id, 
     SUM(value) value 
    FROM 
     source_data 
    GROUP BY 
     CUBE(dimension1, dimension2, dimension3), 
     measure 
), 
    dimension1_label AS(
    SELECT 
     dimension1_id, 
     dimension1_label 
    FROM 
     labels 
    WHERE 
     object = 'dimension1' 
), ... 
SELECT 
    * 
FROM 
    cubed_data 
    JOIN dimension1_label USING (dimension1_id) 
    JOIN dimension2_label USING (dimension2_id) 
    JOIN dimension3_label USING (dimension3_id) 
    JOIN measure_label USING (measure_id) 

El ejemplo es un poco artificial pero espero que muestra el aumento de la claridad en comparación con subconsultas en línea. Los conjuntos de resultados nombrados me han sido de gran ayuda cuando he estado preparando datos para el uso de OLAP. Los conjuntos de resultados con nombre también son obligatorios si tiene/desea crear consultas recursivas.

WITH funciona al menos en las versiones actuales de Postgres, Oracle y SQL Server

+0

La palabra clave WITH es interesante. Definitivamente hace que el código sea mucho más limpio ya que solo puedo referirme al resultado establecido por nombre en las líneas siguientes. – MxyL

3

En general, la gente rompe líneas en palabras reservadas, y el primer guión ningún sub-consultas:

SELECT * 
FROM tablename 
WHERE value in 
    (SELECT * 
    FROM tablename2 
    WHERE condition) 
ORDER BY column 
4

alias de tabla y consistencia sencilla le conseguirán un largo camino largo,

Lo que se ve decente es unas líneas de ruptura en las palabras clave principales SELECT, FROM, WHERE (etc.).

Las uniones pueden ser más complicadas, al marcar la parte ENCENDIDA de las uniones se saca la parte importante de la misma al frente.

Rompiendo expresiones lógicas complicadas (une y donde condiciones ambas) en el mismo nivel también ayuda.

sangría lógicamente el mismo nivel de declaración (subconsultas, la apertura de los soportes, etc.)

mayúsculas todas las palabras clave y funciones estándar.

SQL realmente complejo no va a rehuir los comentarios, aunque por lo general los encuentras en scripts SQL no en SQL dinámico.

ejemplo EDIT:

SELECT a.name, SUM(b.tax) 
FROM db_prefix_registered_users a 
     INNER JOIN db_prefix_transactions b 
      ON a.id = b.user_id 
     LEFT JOIN db_countries 
      ON b.paid_from_country_id = c.id 
WHERE a.type IN (1, 2, 7) AND 
     b.date < (SELECT MAX(date) 
       FROM audit) AND 
     c.country = 'CH' 

Así, al final, para resumir, - importa la coherencia de la mayoría.

2

Colóquelo en una vista para que sea más fácil de visualizar, quizás conserve una captura de pantalla como parte de la documentación. No tiene que guardar la vista ni usarla para ningún otro propósito.

3

En general, sigo un conjunto jerárquico simple de reglas de formato. Básicamente, palabras clave como SELECT, FROM, ORDER BY, todas van en su propia línea. Cada campo va en su propia línea (de forma recursiva)

SELECT 
    F.FIELD1, 
    F.FIELD2, 
    F.FIELD3 
FROM 
    FOO F 
WHERE 
    F.FIELD4 IN 
    (
     SELECT 
      B.BAR 
     FROM 
      BAR B 
     WHERE 
      B.TYPE = 4 
      AND B.OTHER = 7 
    ) 
3

me gusta usar algo como:

SELECT col1, 
      col2, 
      ... 
FROM 
    MyTable as T1 
INNER JOIN 
    MyOtherTable as T2 
     ON t1.col1 = t2.col1 
     AND t1.col2 = t2.col2 
LEFT JOIN 
    ( 
     SELECT 1,2,3 
     FROM Someothertable 
     WHERE somestuff = someotherstuff 
    ) as T3 
    ON t1.field = t3.field 
2

sangría sin duda, pero también se puede dividir las subconsultas se alinee con las observaciones, sus alias nombra algo realmente significativo y especifica a qué subconsulta se refieren, por ejemplo innerCustomer, outerCustomer.

Las expresiones de tabla comunes realmente pueden ayudar en algunos casos a dividir una consulta en secciones significativas.

2

Una vieja pregunta con un millar de opiniones y hay una respuesta correcta, y uno de mis favoritos. Aquí están mis dos centavos.

Con respecto a las subconsultas, últimamente me he encontrado que es más fácil de seguir lo que está pasando con "extrema" sangría y añadiendo los comentarios de este modo:

SELECT mt.Col1, mt.Col2, subQ.Dollars 
from MyTable1 mt 
    inner join (-- Get the dollar total for each SubCol 
       select SubCol, sum(Dollars) Dollars 
       from MyTable2 
       group by SubCol) subQ 
    on subQ.SubCol = mt.Col1 
order by mt.Col2 

En cuanto al otro ciento, sólo se utilizo mayúsculas en la primera palabra Con las páginas de consultas pendientes, es más fácil seleccionarlas cuando comienza una nueva.

Su kilometraje, por supuesto, variará.

9

Muchacho es esta una pregunta cargada. :) Hay tantas maneras de hacerlo bien como personas inteligentes en este sitio. Dicho esto, aquí es cómo me mantengo sano juicio en la construcción de sentencias SQL complejas:

select 
    c.customer_id 
    ,c.customer_name 
    ,o.order_id 
    ,o.order_date 
    ,o.amount_taxable 
    ,od.order_detail_id 
    ,p.product_name 
    ,pt.product_type_name 
from 
    customer c 
inner join 
    order o 
    on c.customer_id = o.customer_id 
inner join 
    order_detail od 
    on o.order_id = od.order_id 
inner join 
    product p 
    on od.product_id = p.product_id 
inner join 
    product_type pt 
    on p.product_type_id = pt.product_type_id 
where 
    o.order_date between '1/1/2011' and '1/5/2011' 
and 
    (
     pt.product_type_name = 'toys' 
    or 
     pt.product_type_name like '%kids%' 
    ) 
order by 
    o.order_date 
    ,pt.product_type_name 
    ,p.product_name 

Si está interesado, me pueden enviar/enviar diseños para inserciones, actualizaciones y eliminaciones, así como subconsultas correlacionadas y compleja predicados de unión .

¿Responde a esta pregunta?

+0

¡Parece que la mayoría de la gente está de acuerdo con el espacio en blanco! – MxyL

+2

Me gusta enfocarme en la atomicidad de cada línea. Usando este patrón, puedo escanear rápidamente la jerarquía del nodo que estoy buscando y luego explorar. El principal inconveniente de esto, en mi experiencia, es que las impresiones se comen papel. En el lado positivo, rara vez envuelven o sangran fuera de la página. –

+1

Lo que me gusta de este diseño es que es fácil comentar partes de la consulta cuando intenta averiguar por qué no arroja los resultados esperados. Siempre es importante al escribir consultas complejas. – HLGEM

3

El única verdadera y correcta manera de dar formato a SQL es:

SELECT t.mycolumn  AS column1 
     ,t.othercolumn  AS column2 
     ,SUM(t.tweedledum) AS column3 
FROM table1 t 
     ,(SELECT u.anothercol 
       ,u.memaw     /*this is a comment*/ 
     FROM table2  u 
       ,anothertable x 
     WHERE u.bla  = :b1  /*the bla value*/ 
     AND x.uniquecol = :b2  /*the widget id*/ 
     ) v 
WHERE t.tweedledee = v.anothercol 
AND t.hohum  = v.memaw 
GROUP BY t.mycolumn 
     ,t.othercolumn 
HAVING COUNT(*) > 1 
; 

;)

serio, me gusta usar con cláusulas (como ya se ha sugerido) para dominar las consultas SQL muy complicados .

2

Guau, muchas respuestas aquí, pero una cosa que no he visto en muchos es ¡COMENTARIOS! Tiendo a agregar muchos comentarios a lo largo, especialmente con grandes sentencias de SQL. El formateo es importante, pero bien colocado y significativo comentarios son extremadamente importantes, no solo para usted, sino para la pobre alma que necesita mantener el código;)