separador query numero monto miles indentar formato fecha decimales dar codigo sql sql-server formatting standards coding-style

query - separador de miles sql



Estándares de formato SQL (26)

En mi último trabajo trabajamos en una gran aplicación de base de datos y desarrollé algunos estándares de formato para que todos escribiéramos SQL con un diseño común. También desarrollamos estándares de codificación, pero estos son más específicos de la plataforma, así que no entraré en ellos aquí.

Me interesa saber qué usan otras personas para los estándares de formato SQL. A diferencia de la mayoría de los entornos de codificación, ya que no he encontrado mucho consenso en línea para ellos.

Para cubrir los principales tipos de consulta:

select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where ST.SourceTableID = X and JT.ColumnName3 = Y

Hubo algún desacuerdo sobre las alimentaciones de línea después de "seleccionar", "de" y "dónde". La intención en la línea de selección es permitir que otros operadores como "X superior" sin alterar el diseño. Después de eso, simplemente mantener un flujo de línea consistente después de los elementos de consulta clave, pareció dar como resultado un buen nivel de legibilidad.

Dejar caer el salto de línea después de "desde" y "dónde" sería una revisión comprensible. Sin embargo, en consultas como la "actualización" a continuación, vemos que el avance de línea después del "dónde" nos da una buena alineación de columnas. Del mismo modo, un salto de línea después de "agrupar por" o "ordenar por" mantiene nuestros diseños de columna claros y fáciles de leer.

update TargetTable set ColumnName1 = @value, ColumnName2 = @value2 where Condition1 = @test

Finalmente un inserto:

insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3 ) values ( @value1, @value2, @value3 )

En su mayor parte, estos no se desvían tanto de la forma en que MS SQL Server Management Studio / query analyzer escribe SQL, sin embargo , difieren.

Estoy ansioso por ver si hay algún consenso en la comunidad de Stack Overflow sobre este tema. Estoy constantemente sorprendido de cuántos desarrolladores pueden seguir el formato estándar para otros idiomas y de repente van tan al azar cuando tocan SQL.


Bonito. Como programador de Python, estas son mis preferencias:

Líneas nuevas después de "seleccionar", "de" y "dónde" solo cuando es necesario para la legibilidad.

Cuando el código de código puede ser más compacto e igualmente legible, generalmente prefiero la forma más compacta. Ser capaz de incluir más código en una pantalla mejora la productividad.

select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where ST.SourceTableID = X and JT.ColumnName3 = Y

En última instancia, esta será una llamada de juicio que se realizará durante la revisión del código.

Para insert , colocaría los parens de manera diferente:

insert into TargetTable ( ColumnName1, ColumnName2, ColumnName3) values ( @value1, @value2, @value3)

El razonamiento para este formato es que si SQL usó idendation para estructura de bloque (como Python), entonces el paréntesis no sería necesario. Entonces, si la sangría se usa de todos modos, los paréntesis deberían tener el efecto mínimo en el diseño. Esto se logra colocándolos al final de las líneas.


Creo que tener unas buenas reglas de formato es realmente importante porque puedes detectar y corregir errores fácilmente. Como se dice: "Está escribiendo código una vez, este código se lee y luego 10000000 de veces", por lo que siempre es bueno dedicar algo de tiempo al formateo. Los objetivos principales son:

  • Haga que su código sea más fácil de leer y entender
  • Minimice el esfuerzo requerido para mantener o extender su código
  • Reduzca la necesidad de que los usuarios y desarrolladores de un sistema consulten fuentes secundarias de documentación, como comentarios de códigos o manuales de software

Algunas reglas que siempre uso:

  • Siempre usa . notación
  • Siempre use alias antes de la columna, entonces. notación
  • Pongo yo and hasta el final de la línea
  • No use soportes de unnishccary
  • No use MAYÚSCULAS
  • Por lo general, prefiere cte a subconsultas anidadas

Como ejemplo, aquí cómo formatearía la consulta utilizada como ejemplo en esta pregunta:

select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from <schema>.SourceTable as ST inner join <schema>.JoinTable as JT on ST.SourceTableID = JT.SourceTableID inner join <schema>.SecondJoinTable as SJT on SJT.SourceTableID = ST.SourceTableID and SJT.Column4 = JT.Column3 where ST.SourceTableID = X and JT.ColumnName3 = Y

Y consulta de "estudiantes":

select term, student_id, case when (ft_credits > 0 and credits >= ft_credits) or (ft_hours_per_week > 3 and hours_per_week >= ft_hours_per_week) then ''F'' else ''P'' end as [status] from ( select a.term, a.student_id, pm.credits as ft_credits, pm.[hours] as ft_hours_per_week, sum(a.credits) as credits, sum(a.hours_per_week) as hours_per_week from ( select e.term, e.student_id, NVL(o.credits, 0) credits, case when NVL(o.weeks, 0) > 5 then (NVL(o.lect_hours, 0) + NVL(o.lab_hours, 0) + NVL(o.ext_hours, 0)) / NVL(o.weeks, 0) else 0 end as hours_per_week from enrollment as e inner join offering as o using (term, offering_id) inner join program_enrollment as pe on pe.student_id = e.student_id and pe.term = e.term and pe.offering_id = e.offering_id where e.registration_code Not in (''A7'', ''D0'', ''WL'') ) as a inner join student_history as sh using (student_id) inner join program_major as pm on pm._major_code = sh.major_code_1 and pm.division_code = sh.division_code_1 where sh.eff_term = ( select max(eff_term) from student_history as shi where shi.student_id = sh.student_id and shi.eff_term <= term ) group by a.term, a.student_id, pm.credits, pm.[hours] ) as a order by term, student_id


El número de opiniones diferentes es aterrador. Esto es lo que mi organización usa:

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y

Mantener la sangría de 8 caracteres es clave para la legibilidad en mi humilde opinión.


Estoy totalmente de acuerdo con su esfuerzo por estandarizar el formato SQL dentro de su proyecto y en general.

También estoy muy de acuerdo con sus opciones de formato. He encontrado casi el mismo, salvo que también sangré las declaraciones ''join'', y con ellas las declaraciones ''on'' una sangría más.

Muy parecido al hecho de que vayas en minúsculas en las palabras clave. ¿Quién quiere recibir esas GRACIAS? También prefiero reducir los alias de la tabla de casos, lo que permite una mejor legibilidad

Muy parecido al hecho de que usas una pequeña sangría (4). Voy con (3).

Considero que los términos "interno" y "externo" no son necesarios.

Aquí es cómo habría formateado su declaración seleccionada:

select st.ColumnName1, jt.ColumnName2, sjt.ColumnName3 from SourceTable st join JoinTable jt on jt.SourceTableID = st.SourceTableID join SecondJoinTable sjt on st.SourceTableID = sjt.SourceTableID and jt.Column3 = sjt.Column4 where st.SourceTableID = X and jt.ColumnName3 = Y ;

Gracias por discutir esto.


Estoy trabajando en la escritura de un formateador de SQL de fuente abierta (SQL Server solo en esta etapa) en C #, así que puse las consultas anteriores a través de él.

Emplea una estrategia similar al OP, es decir, que cada ''sección'' tiene elementos secundarios sangrados debajo. Cuando sea necesario, agrego un espacio en blanco entre las secciones para ayudar a la claridad; estas no se agregarán cuando no haya uniones o un mínimo donde las condiciones

Resultado:

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND ST.SourceTable2ID = SJT.SourceTable2ID WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y AND JT.Column3 = SJT.Column4 ORDER BY ST.ColumnName1


Hay muchos puntos buenos en este hilo. El único estándar que he intentado convencer a las personas para que utilicen es colocar la coma en la misma línea antes de cada columna. Al igual que:

Select column1 ,column2 ,column3 ,column4 ,Column5 ...ect

Oposición a:

Select column1, column2, column3, ect...

La razón por la que prefiero esta práctica es porque, si es necesario, puedes comentar una línea y no habrá un problema de coma cuando lo ejecutes debido a que la coma correspondiente está siendo comentada también. Sé que vi a otro usuario en el hilo que también lo había hecho pero que en realidad no lo señaló. No es una gran revelación para llevar a la conversación, pero mis dos centavos. Gracias


Llego tarde a la fiesta, pero solo agregaré mi estilo de formato preferido, que debo haber aprendido de libros y manuales: es compacto. Aquí está la declaración SELECT muestra:

SELECT st.column_name_1, jt.column_name_2, sjt.column_name_3 FROM source_table AS st INNER JOIN join_table AS jt USING (source_table_id) INNER JOIN second_join_table AS sjt ON st.source_table_id = sjt.source_table_id AND jt.column_3 = sjt.column_4 WHERE st.source_table_id = X AND jt.column_name_3 = Y

En resumen: sangría de 8 espacios, palabras clave en mayúsculas (aunque SO los colorea mejor cuando está en minúsculas), sin camelcase (sin sentido en Oracle) y envolturas de línea cuando sea necesario.

La UPDATE :

UPDATE target_table SET column_name_1 = @value, column_name_2 = @value2 WHERE condition_1 = @test

Y el INSERT :

INSERT INTO target_table (column_name_1, column_name_2, column_name_3) VALUES (@value1, @value2, @value3)

Ahora, déjame ser el primero en admitir que este estilo tiene sus problemas. La sangría de 8 espacios significa que ORDER BY y GROUP BY desalinean la sangría o dividen la palabra BY off por sí misma. También sería más natural aplicar sangría al predicado completo de la cláusula WHERE , pero generalmente alineo los siguientes operadores AND y OR en el margen izquierdo. La sangría después de las líneas envueltas INNER JOIN también es algo arbitraria.

Pero por alguna razón, todavía me resulta más fácil de leer que las alternativas.

Terminaré con una de mis creaciones más complejas últimamente usando este estilo de formateo. Casi todo lo que encontrarías en una declaración SELECT aparece en este. (También se ha alterado para ocultar sus orígenes, y es posible que haya introducido errores al hacerlo).

SELECT term, student_id, CASE WHEN ((ft_credits > 0 AND credits >= ft_credits) OR (ft_hours_per_week > 3 AND hours_per_week >= ft_hours_per_week)) THEN ''F'' ELSE ''P'' END AS status FROM ( SELECT term, student_id, pm.credits AS ft_credits, pm.hours AS ft_hours_per_week, SUM(credits) AS credits, SUM(hours_per_week) AS hours_per_week FROM ( SELECT e.term, e.student_id, NVL(o.credits, 0) credits, CASE WHEN NVL(o.weeks, 0) > 5 THEN (NVL(o.lect_hours, 0) + NVL(o.lab_hours, 0) + NVL(o.ext_hours, 0)) / NVL(o.weeks, 0) ELSE 0 END AS hours_per_week FROM enrollment AS e INNER JOIN offering AS o USING (term, offering_id) INNER JOIN program_enrollment AS pe ON e.student_id = pe.student_id AND e.term = pe.term AND e.offering_id = pe.offering_id WHERE e.registration_code NOT IN (''A7'', ''D0'', ''WL'') ) INNER JOIN student_history AS sh USING (student_id) INNER JOIN program_major AS pm ON sh.major_code_1 = pm._major_code AND sh.division_code_1 = pm.division_code WHERE sh.eff_term = ( SELECT MAX(eff_term) FROM student_history AS shi WHERE sh.student_id = shi.student_id AND shi.eff_term <= term) GROUP BY term, student_id, pm.credits, pm.hours ) ORDER BY term, student_id

Esta abominación calcula si un estudiante es a tiempo completo o a tiempo parcial en un término determinado. Independientemente del estilo, este es difícil de leer.


Me doy cuenta de que llegué muy tarde a este debate, pero me gustaría dar mi opinión. Definitivamente estoy a favor de las comas al inicio de la línea. Como dices AdamRalph es más fácil comentar un campo y también me resulta más difícil perder una coma accidentalmente cuando están al principio, aunque esto no suena como un problema importante. He pasado horas tratando de hacerlo en el pasado. para rastrear errores de sintaxis accidentales en largos procedimientos de T-SQL donde accidentalmente he perdido una coma al final de la línea (estoy seguro de que algunos de ustedes probablemente lo hayan hecho también). También estoy a favor de aliasing tanto como sea posible.

En general, me doy cuenta de que todo se reduce a las preferencias personales, lo que funciona para algunos no lo es para los demás. Siempre que pueda leer el código fácilmente y cada desarrollador muestre cierta consistencia en su estilo, creo que eso es lo más importante.


Me gusta que mi SQL esté formateado de esa manera, aunque mientras la intención sea fácil de leer, la mayoría de los formatos funcionarán. Realmente odio ver las declaraciones creadas en el diseñador de consultas y luego me fui de esa manera. Si estoy editando el procedimiento / vista / función / disparador de otra persona, etc., intentaré mantener el formato ya utilizado (a menos que sea realmente malo, lo reformatearé todo).

Seleccionar declaración

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE (ST.SourceTableID = X) AND (JT.ColumnName3 = Y);

Declaración de actualización

UPDATE TargetTable SET ColumnName1 = @value, ColumnName2 = @value2 WHERE (Condition1 = @test);

Insertar declaración

INSERT INTO TargetTable ( ColumnName1, ColumnName2, ColumnName3 ) values ( @value1, @value2, @value3 );


Me gusta:

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 --leave all selected columns on the same line FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT --only splitting lines when more than 1 condition ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X and JT.ColumnName3 = Y

para obtener más código en un área de visualización más pequeña. También creo que las palabras clave deben estar en mayúsculas


Mejor tarde que nunca. Utilizo un estilo diferente y lo adopté de un muy buen desarrollador de SQL con el que solía trabajar. Alineo correctamente las palabras clave y utilizo las letras MAYÚSCULAS para facilitar la escritura. Las palabras clave serán resaltadas por el editor y no veo la necesidad de que estén en MAYÚSCULAS a menos que haga mucha edición en editores de texto que no admite funciones de resaltado de palabras clave. No intento que sea compacto, sino más legible y alineado verticalmente tanto como sea posible. Aquí hay un ejemplo de selección tomada de @BenLaan respuesta escrita en mi formato:

select st.ColumnName1 , jt.ColumnName2 , sjt.ColumnName3 from SourceTable st inner join JoinTable jt on jt.SourceTableID = st.SourceTableID inner join SecondJoinTable sjt on st.SourceTableID = sjt.SourceTableID and st.SourceTable2ID = sjt.SourceTable2ID where st.SourceTableID = X and jt.ColumnName3 = Y and jt.Column3 = sjt.Column4 order by st.ColumnName1

Tratar de conformar a todo el equipo para seguir el mismo patrón de formateo es lo más difícil. Seguiría cualquier formato si todos los demás siguieran el mismo camino, pero nunca ha sido la misma historia.

ACTUALIZACIÓN: Reescribiendo una de las consultas complejas mencionadas en publicaciones anteriores:

select term , student_id , case when((ft_credits > 0 and credits >= ft_credits) or (ft_hours_per_week > 3 and hours_per_week >= ft_hours_per_week)) then ''F'' else ''P'' end as status from (select term , student_id , pm.credits AS ft_credits , pm.hours AS ft_hours_per_week , SUM(credits) AS credits , SUM(hours_per_week) AS hours_per_week from (select e.term , e.student_id , nvl(o.credits, 0) credits , case when nvl(o.weeks, 0) > 5 then (nvl(o.lect_hours, 0) + nvl(o.lab_hours, 0) + nvl(o.ext_hours, 0)) / nvl(o.weeks, 0) else 0 end as hours_per_week from enrollment as e inner join offering as o using (term, offering_id) inner join program_enrollment as pe on e.student_id = pe.student_id and e.term = pe.term and e.offering_id = pe.offering_id where e.registration_code not in (''A7'', ''D0'', ''WL'') ) inner join student_history as sh using (student_id) inner join program_major as pm on sh.major_code_1 = pm._major_code and sh.division_code_1 = pm.division_code where sh.eff_term = (select max(eff_term) from student_history as shi where sh.student_id = shi.student_id and shi.eff_term <= term) group by term, student_id, pm.credits, pm.hours ) order by term, student_id


Mi estilo preferido:

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 FROM SourceTable ST INNER JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y AND JT.Column3 = SJT.Column4


Nadie ha hecho expresiones comunes de tablas (CTE) todavía. A continuación lo incorpora junto con algunos otros estilos que uso:

@declare @tableVariable ( colA1 int, colA2 int, colB1 int, colB2 nvarchar(255), colB3 nvarchar(255), colB4 int, colB5 bit, computed int ); with getSomeData as ( select st.colA1, sot.colA2 from someTable st inner join someOtherTable sot on st.key = sot.key ), getSomeOtherData as ( select colB1, colB2, colB3, colB4, colB5, computed = case when colB5 = 1 then ''here'' when colB5 = 2 then ''there'' end from aThirdTable tt inner hash join aFourthTable ft on tt.key1 = ft.key2 and tt.key2 = ft.key2 and tt.key3 = ft.key3 ) insert @tableVariable ( colA1, colA2, colA2, colB1, colB2, colB3, colB4, colB5, computed ) select colA1, colA2, colB1, colB2, colB3, colB4, colB5, computed from getSomeData data1 join getSomeOtherData data2

Algunos puntos en el formato CTE:

  • En mi CTE "con" está en una línea separada, y todo lo demás en el cte está sangrado.
  • Mis nombres de CTE son largos y descriptivos. Los CTE pueden ser complejos y los nombres descriptivos son muy útiles.
  • Por alguna razón, me encuentro prefiriendo los verbos para los nombres CTE. Lo hace parecer más animado
  • Estilo similar con los paréntesis como Javascript hace con sus llaves. También es así como hago las llaves en C #.

Esto simula:

func getSomeData() { select st.colA1, sot.colA2 from someTable st inner join someOtherTable sot on st.key = sot.key }

Algunos puntos además del formato CTE:

  • Dos pestañas después de "seleccionar" y otras palabras clave. Eso deja suficiente espacio para "unión interna", "agrupar por", etc. Puede ver un ejemplo anterior donde eso no es cierto. Pero la "combinación interna de hash" DEBE parecer fea. Sin embargo, en este punto, probablemente voy a experimentar con algunos de los estilos anteriores en el futuro.
  • Las palabras clave son minúsculas. Su coloración por el IDE y su estado de indentación especial los resaltan lo suficiente. Me reservo mayúsculas para otras cosas que quiero enfatizar basadas en la lógica local (de negocios).
  • Si hay pocas columnas, las pongo en una fila (getSomeData). Si hay algunos más, los verticalizo (getSomeOtherData). Si hay demasiada verticalización en una unidad, horizontalizo algunas columnas en la misma línea agrupada por lógica definida localmente (el segmento final de inserción y selección). Por ejemplo, pondría información de nivel escolar en una línea, nivel de estudiante en otra, etc.
  • Especialmente cuando se está verticalizando, prefiero el nombre "varname = colname + something syntax" del servidor sql a "colname + something as varname".
  • Duplique el último punto si estoy tratando con una declaración de caso.
  • Si cierta lógica se presta a un estilo de ''matriz'', me ocuparé de las consecuencias del tipeo. Eso es más o menos lo que está sucediendo con la declaración del caso, donde los ''whens'' y ''then''s están alineados.

Encuentro que estoy más centrado en mi estilo CTE que en otras áreas. No he experimentado con los estilos más similares a los planteados en la pregunta. Probablemente lo haga algún día y vea cómo me gusta. Probablemente estoy maldito por estar en un ambiente donde es una elección, aunque es una maldición divertida de tener.


Sí, puedo ver el valor de diseñar su sql de una manera rigurosamente definida, pero seguramente la convención de nomenclatura y su intención son mucho más importantes. Como 10 veces más importante.

Basado en que mi mascota odia son las tablas con el prefijo tbl, y los procedimientos almacenados con el prefijo sp - sabemos que son tablas y SP. La denominación de objetos DB es mucho más importante que la cantidad de espacios que hay

Solo mi valor de $ 0.02


Si realizo cambios en T-SQL ya escrito, entonces sigo la convención ya usada (si la hay).

Si estoy escribiendo desde cero o no hay una convención, entonces tiendo a seguir su convención dada en la pregunta, excepto que prefiero usar mayúsculas para las palabras clave (solo una preferencia personal para la legibilidad).

Creo que con el formato SQL como con otras convenciones de formato de código, el punto importante es tener una convención, no lo que esa convención es (¡dentro de los dominios del sentido común, por supuesto!)


Soy de la opinión de que siempre que pueda leer el código fuente fácilmente, el formato es secundario. Siempre que se logre este objetivo, hay una serie de buenos estilos de diseño que pueden adoptarse.

El único otro aspecto que es importante para mí es que sea cual sea el diseño / estilo de codificación que elija adoptar en su tienda, asegúrese de que todos los programadores la utilicen de manera uniforme.

Solo para su referencia, aquí es cómo presentaría el ejemplo que proporcionó, solo mi preferencia de diseño. De particular interés, la cláusula ON está en la misma línea que la unión, solo la condición de unión primaria se enumera en la unión (es decir, la coincidencia de tecla) y otras condiciones se mueven al cluase de donde.

select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID where ST.SourceTableID = X and JT.ColumnName3 = Y and JT.Column3 = SJT.Column4

Un consejo: obtén una copia de SQL Prompt de Red Gate. Puede personalizar la herramienta para usar las preferencias de diseño deseadas y, a continuación, los programadores de su tienda pueden usarla para garantizar que todos adopten los mismos estándares de codificación.


Sugeriría el siguiente estilo, basado en la sugerencia de John:

/* <Query title> <Describe the overall intent of the query> <Development notes, or things to consider when using/interpreting the query> */ select ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3 from -- <Comment why this table is used, and why it''s first in the list of joins> SourceTable ST -- <Comment why this join is made, and why it''s an inner join> inner join JoinTable JT on ST.SourceTableID = JT.SourceTableID -- <Comment why this join is made, and why it''s an left join> left join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID and JT.Column3 = SJT.Column4 where -- comment why this filter is applied ST.SourceTableID = X -- comment why this filter is applied and JT.ColumnName3 = ( select somecolumn from sometable ) ;

Ventajas:
- Los comentarios son una parte esencial para hacer que el código sea legible y para detectar errores.
- Agregar -todos los filtros "a" a la unión evita errores al cambiar de unión interna a izquierda.
- Colocar el punto y coma en una nueva línea permite añadir / comentar fácilmente las cláusulas where.


Tarde, pero voy a lanzar mi sombrero en el ring. Lleva un poco más de tiempo escribir, pero descubro que surgen patrones con la alineación vertical que lo hacen muy legible una vez que está acostumbrado.

SELECT ST.ColumnName1, JT.ColumnName2, SJT.ColumnName3, CASE WHEN condition1 = True AND condition2 = True Then DoSomething Else DoSomethingElse END ColumnName4 FROM SourceTable AS ST INNER JOIN JoinTable AS JT ON JT.SourceTableID = ST.SourceTableID INNER JOIN SecondJoinTable AS SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 LEFT JOIN (SELECT Column5 FROM Table4 QUALIFY row_number() OVER ( PARTITION BY pField1, pField2 ORDER BY oField1 ) = 1 ) AS subQry ON SJT.Column5 = subQry.Column5 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y


Tiendo a usar un diseño similar al suyo, aunque incluso voy unos pasos más allá, por ejemplo:

select ST.ColumnName1 , JT.ColumnName2 , SJT.ColumnName3 from SourceTable ST inner join JoinTable JT on JT.SourceTableID = ST.SourceTableID inner join SecondJoinTable SJT on ST.SourceTableID = SJT.SourceTableID where ST.SourceTableID = X and JT.ColumnName3 = Y and JT.Column3 = SJT.Column4

Tal vez se vea un poco exagerado al principio, pero en mi humilde opinión, el uso de la tabulación proporciona el diseño más limpio y sistemático dada la naturaleza declarativa de SQL.

Probablemente termines con todo tipo de respuestas aquí, al final depende de las preferencias personales o del equipo acordado.


Utilizo un formato similar al tuyo, excepto que puse la palabra clave "ON" en la misma línea que la unión y puse los operadores "AND" y "OR" al final de las líneas para que todos mis criterios de unión / selección se alineen bien.

Si bien mi estilo es similar al de John Sansom, no estoy de acuerdo con poner criterios de unión en la cláusula WHERE. Creo que debería ser con la tabla unida para que esté organizada y sea fácil de encontrar.

También tiendo a poner paréntesis en líneas nuevas, alineado con la línea de arriba y luego sangrando en la línea siguiente, aunque para las declaraciones cortas puedo mantener los paréntesis en la línea original. Por ejemplo:

SELECT my_column FROM My_Table WHERE my_id IN ( SELECT my_id FROM Some_Other_Table WHERE some_other_column IN (1, 4, 7) )

Para las sentencias CASE doy una nueva línea y sangría para cada WHEN y ELSE y alineo el END de nuevo con CASE:

CASE WHEN my_column = 1 THEN ''one'' WHEN my_column = 2 THEN ''two'' WHEN my_column = 3 THEN ''three'' WHEN my_column = 4 THEN ''four'' ELSE ''who knows'' END



Respuesta tardía pero con suerte útil

Mi experiencia trabajando como parte del equipo de desarrollo más grande es que puedes seguir adelante y definir los estándares que te gusten, pero el problema es hacerlos cumplir o hacer que sea muy fácil de implementar para los desarrolladores.

Como desarrolladores, a veces creamos algo que funciona y luego decimos "Voy a formatearlo más tarde", pero eso luego nunca llega.

Inicialmente usamos SQL Prompt (fue genial) para esto, pero luego cambiamos a ApexSQL Refactor porque es una herramienta gratuita.


Cien respuestas aquí ya, pero después de mucho ir y venir en los últimos años, esto es lo que he decidido por:

SELECT ST.ColumnName1 , JT.ColumnName2 , SJT.ColumnName3 FROM SourceTable ST JOIN JoinTable JT ON JT.SourceTableID = ST.SourceTableID JOIN SecondJoinTable SJT ON ST.SourceTableID = SJT.SourceTableID AND JT.Column3 = SJT.Column4 WHERE ST.SourceTableID = X AND JT.ColumnName3 = Y

Sé que esto puede hacer para ficheros diff desordenado como una mesa adicional podría causar mí para volver a sangrar muchas líneas de código, pero para mi facilitar la lectura, me gusta.


Parece ser que la mayoría de ustedes todavía trabajan en los monitores que sólo soportan 800x600. Mis monitores harán 1920x1080, así que quiero utilizar todo ese espacio a la derecha.

Qué tal esto:

select col1, col2, col3 , case when x = 1 then ''answer1'' else ''answer2'' end , col4, col5, col6, col7 from table1 t1 inner join table2 t2 on t1.col1 = t2.col1 and t1.col2 and t2.col2 where t1.col5 = 19 and t1.col7 = ''Bill Gates''


SELECT a.col1 AS [Column1] ,b.col2 AS [Column2] ,c.col1 AS [Column3] FROM Table1 a INNER JOIN Table2 b ON b.Id = a.bId INNER JOIN Table3 c ON c.Id = a.cId WHERE a.col = X AND b.col = Y

Utiliza muchas más líneas que muchos de los ejemplos aquí, pero creo que es mucho más fácil de entender, permite la eliminación rápida de columnas / cláusulas / tablas. Ayuda a aprovechar un monitor orientado verticalmente.


SELECT st.ColumnName1 ,jt.ColumnName2 ,sjt.ColumnName3 FROM SourceTable st JOIN JoinTable jt ON jt.SourceTableID = st.SourceTableID JOIN SecondJoinTable sjt ON SstT.SourceTableID = sjt.SourceTableID AND jt.Column3 = sjt.Column4 WHERE st.SourceTableID = X AND jt.ColumnName3 = Y

Yo uso todas las tapas de las palabras acciones, se une o cláusulas, se destacan mejor. JOIN es el mismo que el INNER JOIN por lo interior no necesita ser escrita a cabo, se supone, escribir OUTER JOIN o LEFT JOIN cuando lo necesite. También uso lowere caso de mis nombres de alias. causa común frente a cabo si se comente la última columna que hay que contentarse con una coma arriba y la consulta falla.