78

缩进 SQL 语句的公认做法是什么?例如,考虑以下 SQL 语句:

SELECT column1, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
FROM table2
INNER JOIN table3
ON table2.column1 = table3.column1
)

这应该如何缩进?非常感谢。

4

24 回答 24

47
SELECT column1
     , column2
FROM table1
WHERE column3 IN
(
    SELECT TOP(1) column4
    FROM table2
    INNER JOIN table3
    ON table2.column1 = table3.column1
)

我喜欢把所有的“,”放在前面,这样当 SQL 编辑器在 X 行出现错误时,我永远不会搜索它们。


这是不使用这种编写 SQL 语句的人的示例。两者都包含缺少逗号的错误。

SELECT sdcolumn123
 , dscolumn234
 , sdcolumn343
 , ffcolumn434
 , sdcolumn543
 , bvcolumn645
  vccolumn754
 , cccolumn834
 , vvcolumn954
 , cvcolumn104
FROM table1
WHERE column3 IN
(
    ...
)

SELECT sdcolumn123, dscolumn234, asdcolumn345, dscolumn456, ascolumn554, gfcolumn645 sdcolumn754, fdcolumn845, sdcolumn954, fdcolumn1054
FROM table1
WHERE column3 IN
(
    ...
)

在第一个示例中,我发现更简单、更快捷。希望这个例子能更多地展示我的观点。

于 2008-11-07T14:31:25.520 回答
28
SELECT column1, column2
FROM table
WHERE column3 IN (
    SELECT TOP(1) column4
    FROM table2
    INNER JOIN table3 ON table2.column1 = table3.column1
)

这非常简短且易于阅读。如果选择了更多列或更多连接条件,我会进行调整。

于 2008-11-07T14:30:47.690 回答
24

不确定是否有公认的做法,但现在我会这样做:

SELECT 
    column1, 
    column2 
FROM 
    table1 
WHERE 
    column3 IN 
    ( 
     SELECT TOP(1) 
         column4 
     FROM 
         table2 
         INNER JOIN 
         table3 
             ON table2.column1 = table3.column1 
    )
于 2008-11-07T14:31:20.933 回答
20

我喜欢在代码中有“河流”的空白。它使扫描更容易一些。

SELECT column1,
       column2
  FROM table1
 WHERE column3 IN (SELECT column4
                     FROM table2
                     JOIN table3
                       ON table2.column1 = table3.column1);
于 2008-11-07T14:41:01.897 回答
18

我喜欢 jalbert 将关键字排列在右侧的形式。我还要补充一点,我喜欢左边的 AND 和 OR(有些人把它们放在右边。)此外,我喜欢尽可能排列我的等号。


SELECT column1, 
       column2  
  FROM table1, table2 
 WHERE table1.column1 = table2.column4 
   AND table1.col5    = "hi" 
    OR table2.myfield = 678 
于 2008-11-07T15:03:44.440 回答
13

这是我个人的方法。根据连接条件的长度,我有时会在下面的行上缩进它。

SELECT
  column1,
  column2
FROM
  table1
WHERE
  column3 IN ( 
    SELECT TOP(1)
      column4
    FROM
      table2
      INNER JOIN table3 ON table2.column1 = table3.column1
  )


SELECT
  column1,
  column2
FROM
  table1
WHERE
  column3 IN ( 
    SELECT TOP(1)
      column4
    FROM
      table2
      INNER JOIN table3
        ON table2.column1 = table3.column1 -- for long ones
  )
于 2008-11-07T14:30:42.900 回答
8

我为我们的商店编写了一个代码标准,该标准极度偏向于可读性/“可发现性”(后者主要在插入-选择语句中有用):

SELECT 
    column1, 
    column2
FROM 
    table1
WHERE 
    column3 IN
    (
        SELECT TOP(1) 
            column4
        FROM 
            table2
            INNER JOIN table3 ON table2.column1 = table3.column1
    )

在更复杂的查询中,它的用处变得更加明显:

SELECT
    Column1,
    Column2,
    Function1
    (
        Column1,
        Column2
    ) as Function1,
    CASE
    WHEN Column1 = 1 THEN
        a
    ELSE
        B
    END as Case1       
FROM
    Table1 t1
    INNER JOIN Table2 t2 ON t1.column12 = t2.column21
WHERE
    (
        FilterClause1
        AND FilterClause2
    )
    OR
    (
        FilterClause3
        AND FilterClause4
    )

一旦您迁移到在大多数查询中具有多个连接的系统,根据我的经验,自由使用垂直空间是您处理复杂 SQL 的最佳朋友。

于 2008-11-07T15:17:27.610 回答
7

SQL 格式化是一个存在大量差异和分歧的领域......但首先,我喜欢关注可读性,并认为无论你做什么,始终遵守任何降低可读性的规则,就像老套路所说的那样, “愚蠢的一致性”(“愚蠢的一致性是简单头脑的妖精”)

因此,这里有一些准则,而不是称它们为规则。对于 SQL 语句中的每个主要子句(Select、Insert、Delete、From、Where、Have、Group BY、Order By ......我可能会遗漏一些)应该很容易识别。因此,我通常将它们缩进最高级别,甚至彼此缩进。然后在每个子句中,我均匀地缩进下一个逻辑子结构......等等......但是如果在任何个别情况下这样做会更易读,我可以随意(并且经常这样做)更改模式......复杂案例语句就是一个很好的例子。因为任何需要水平滚动的东西都会极大地降低可读性,所以我经常在多行上编写复杂的(嵌套的)Case 表达式。当我这样做时,我会尝试根据它在 SQL 语句中的逻辑位置来保持这种语句的开头悬挂缩进,

SQL 数据库代码已经存在很长时间了,因为在计算机使用小写字母之前,所以历史上对大写关键字的偏好,但我更喜欢可读性而不是传统......(现在我使用的每个工具都使用颜色编码关键字反正)

我还会使用表别名来减少眼睛必须扫描的文本量,以便了解查询的结构,只要别名不会造成混淆。在少于 3 或 4 个表的查询中,单字符别名很好,如果所有表都以不同的字母开头,我经常使用表的第一个字母......同样,任何最有助于可读性的东西。最后,如果您的数据库支持它,许多关键字都是可选的,(如别名的“Inner”、“Outer”、“As”等)“Into”(来自 Insert Into)在 Sql Server 上是可选的 - 但不是在 Oracle 上)因此,如果您的代码需要独立于平台,请小心使用它...

你的例子,我会写成:

Select column1, column2
From table1 T1
Where column3 In (Select Top(1) column4
                  From table2 T2
                     Join table3 T3
                         On T2.column1 = T3.column1)

或者

Select column1, column2
From table1 T1
Where column3 In 
     (Select Top(1) column4
      From table2 T2
         Join table3 T3
            On T2.column1 = T3.column1)

如果 select 子句中有更多列,我会缩进第二行和后续行...我通常不遵守任何严格的(每行一列)规则,因为垂直滚动几乎与水平滚动一样不利于可读性是,特别是如果只有屏幕的前十列有任何文本)

Select column1, column2, Col3, Col4, column5,
    column6, Column7, isNull(Column8, 'FedEx') Shipper,
    Case Upper(Column9) 
       When 'EAST'  Then 'JFK'
       When 'SOUTH' Then 'ATL'
       When 'WEST'  Then 'LAX'
       When 'NORTH' Then 'CHI' End HubPoint
From table1 T1
Where column3 In 
     (Select Top(1) column4
      From table2 T2
         Join table3 T3
            On T2.column1 = T3.column1)

以任何方式格式化代码使其最易读......

于 2008-11-07T15:02:15.753 回答
7

如果你有一个冗长的 SQL 语句,你想重新格式化而不需要所有的打字和制表符,你可以把它放到这个网站上,得到一个格式很好的结果。您可以尝试各种格式,看看哪种格式使您的文本最易读。

编辑:我相信是 SQL 格式化程序的 2014 年位置。

于 2008-11-07T15:27:58.713 回答
5

我喜欢让查询的不同部分垂直排列。我倾向于为 SQL 使用 8 个空格的制表符,这似乎效果很好。

SELECT  column1, 
        column2
FROM    table1
WHERE   column3 IN
(
        SELECT TOP(1) column4
        FROM    table2
        INNER JOIN table3
        ON      table2.column1  = table3.column1
)
于 2008-11-07T14:44:48.143 回答
5

缩进非常非常复杂的 SQL 的示例:

SELECT 
    produtos_cesta.cod_produtos_cesta, 
    produtos.nome_pequeno,
    tab_contagem.cont,
    produtos_cesta.sku, 
    produtos_kits.sku_r AS sku_kit, 
    sku_final = CASE
        WHEN produtos_kits.sku_r IS NOT NULL THEN produtos_kits.sku_r
        ELSE produtos_cesta.sku
    END,
    estoque = CASE
        WHEN produtos2.estoque IS NOT NULL THEN produtos2.estoque
        ELSE produtos.estoque
    END,
    produtos_cesta.unidades as unidades1, 
    unidades_x_quantidade = CASE
        WHEN produtos.cod_produtos_kits_tipo = 1 THEN CAST(produtos_cesta.quantidade * (produtos_cesta.unidades / tab_contagem.cont) * produtos_kits.quantidade AS int)
        ELSE CAST(produtos_cesta.quantidade * produtos_cesta.unidades AS int)
    END,
    unidades = CASE
        WHEN produtos.cod_produtos_kits_tipo = 1 THEN produtos_cesta.unidades / tab_contagem.cont * produtos_kits.quantidade
        ELSE produtos_cesta.unidades
    END,
    unidades_parent = produtos_cesta.unidades,
    produtos_cesta.quantidade,
    produtos.controla_estoque, 
    produtos.status
FROM 
    produtos_cesta 
INNER JOIN produtos 
    ON (produtos_cesta.sku = produtos.sku) 
INNER JOIN produtos_pacotes 
    ON (produtos_cesta.sku = produtos_pacotes.sku) 
INNER JOIN (
    SELECT 
        produtos_cesta.cod_produtos_cesta,
        cont = SUM(
            CASE
                WHEN produtos_kits.quantidade IS NOT NULL THEN produtos_kits.quantidade
                ELSE 1
            END
        )
    FROM 
        produtos_cesta 
    LEFT JOIN produtos_kits 
        ON (produtos_cesta.sku = produtos_kits.sku) 
    LEFT JOIN produtos 
        ON (produtos_cesta.sku = produtos.sku) 
    WHERE 
        shopper_id = '" + mscsShopperId + @"' 
    GROUP BY 
        produtos_cesta.cod_produtos_cesta, 
        produtos_cesta.sku, 
        produtos_cesta.unidades 
) 
AS tab_contagem
    ON (produtos_cesta.cod_produtos_cesta = tab_contagem.cod_produtos_cesta)
LEFT JOIN produtos_kits 
    ON (produtos.sku = produtos_kits.sku) 
LEFT JOIN produtos as produtos2
    ON (produtos_kits.sku_r = produtos2.sku) 
WHERE 
    shopper_id = '" + mscsShopperId + @"' 
GROUP BY 
    produtos_cesta.cod_produtos_cesta, 
    tab_contagem.cont,
    produtos_cesta.sku, 
    produtos_kits.sku_r, 
    produtos.cod_produtos_kits_tipo, 
    produtos2.estoque,
    produtos.controla_estoque, 
    produtos.estoque, 
    produtos.status, 
    produtos.nome_pequeno, 
    produtos_cesta.unidades, 
    produtos_cesta.quantidade,
    produtos_kits.quantidade
ORDER BY 
    produtos_cesta.sku, 
    produtos_cesta.unidades DESC
于 2010-08-21T01:01:51.607 回答
5

由于上面大多数都排列了返回列名,我发现排列表名和条件有助于提高可读性。

SELECT 
    column1, 
    column2
FROM 
    table1
WHERE 
    column3 IN
    (
        SELECT TOP(1) 
            column4
        FROM 
            table2 INNER JOIN 
            table3 ON table2.column1 = table3.column1
    )

当加入条件变长时。

SELECT
    Column1,
    Column2
FROM 
    Table1 JOIN 
    Table2 ON 
        Table1.Column3 = Table2.Column4 JOIN 
    Table3 ON 
        Table2.Column1 = Table3.Column1 and
        Table2.ColumnX = @x and
        Table3.ColumnY = @y
WHERE
    Condition1=xxx and
    Condition2=yyy and
    (
        Condition3=aaa or
        Condition4=bbb
    )
于 2012-03-28T15:04:37.873 回答
5

这是我对此的看法:

select column1, column2
    from table1
    where (column3 in (
        select top(1) column4
            from table2
            inner join table3
                on (table2.column1 = table3.column1)
    ))
;
  • 全部小写,因为它更容易阅读小写字符(我们有代码突出显示来强调关键字)也更容易输入
  • 关键字上的每个限制或选项(例如 select 上的 from 或 join 上的 on )都缩进以显示它们对outward关键字的依赖性
  • 右括号与开头的缩进级别相同
  • 在 where 和 on 子句中使用括号以增加可读性
  • 让分号在同一缩进处关闭选择语句,以便更好地区分多个语句(如果您需要像 SAS PROC SQL 那样的语言中的分号)
  • 它仍然非常紧凑,不会在整个页面上伸展
于 2013-08-07T08:54:50.883 回答
4

当然,这取决于个人喜好。如果在团队环境中,为了保持一致性,应该在成员之间达成一致。但这将是我的偏好:

SELECT column1, column2
FROM   table1
WHERE  column3 IN(SELECT     TOP(1) column4
                  FROM       table2
                  INNER JOIN table3 ON
                             table2.column1 = table3.column1
                 )
于 2008-11-07T14:32:22.553 回答
3

我会这样格式化:

SELECT
    column1, 
    column2
FROM 
    table1
WHERE 
    column3 IN (SELECT TOP(1) 
                    column4 
                FROM 
                    table2 
                    INNER JOIN table3 ON table2.column1 = table3.column1)

或像这样:

SELECT
    column1, 
    column2
FROM 
    table1
WHERE 
    column3 IN (SELECT TOP(1) column4 
                FROM table2 
                INNER JOIN table3 ON table2.column1 = table3.column1)
于 2008-11-07T14:34:04.077 回答
2

这是我的正常偏好:

    SELECT column1
        ,column2
    FROM table1
    WHERE column3 IN (
        SELECT TOP(1) column4
        FROM table2
        INNER JOIN table3
            ON table2.column1 = table3.column1
    )
于 2008-11-07T14:41:26.997 回答
2

好吧,当然这取决于查询。

对于简单的查询,一个高度正式的缩进方案只是麻烦多于它的价值,实际上会使代码可读性降低,而不是更多。但是随着复杂性的增加,您需要开始更加小心地构建语句,以确保以后可以再次阅读。

于 2008-11-07T14:45:43.977 回答
2

是的,这是相当主观的......但这是我的 2 美分:

SELECT
   Column1,
   Column2
FROM Table1
WHERE 
   Column3 IN (
      SELECT Column4
      FROM Table2
      JOIN Table3 ON
         Table2.Column1 = Table3.Column1
   )

但是,真的,我可能会在没有 IN 的情况下重写它:

SELECT
   Column1,
   Column2
FROM Table1
JOIN Table2 ON
   Table1.Column3 = Table2.Column4
JOIN Table3 ON
   Table2.Column1 = Table3.Column1

基本上,我的规则是:

  • 大写关键字
  • 列在单独的行上,但 SELECT 修饰符(SELECT TOP 100、SELECT DISTINCT 等)或单个列(SELECT 1、SELECT Id、SELECT * 等)在同一行上
  • 在 JOIN 子句下缩进的连接条件
  • 将 JOIN 用于 INNER JOIN(因为它是常见的),并完全指定其他(LEFT OUTER JOIN、FULL OUTER JOIN 等)
  • 在同一行打开括号,在单独的行关闭括号。如果您有别名,则别名与紧括号一起使用。
于 2008-11-07T14:52:18.177 回答
2

我刚刚把它通过我的 SQL 美化器,结果是这样的......

SELECT column1, column2
FROM table1
WHERE column3 IN
(
SELECT TOP(1) column4
    FROM table2
            INNER JOIN table3
            ON table2.column1 = table3.column1
)

http://extras.sqlservercentral.com/prettifier/prettifier.aspx

.....但是我还没有找到一种将颜色输入 StackOverflow 的方法。

于 2008-11-07T16:40:56.647 回答
1

我不知道是否有标准,但我喜欢这样做;

SELECT column1, column2
  FROM table1
WHERE column3 IN
(
    SELECT TOP(1) column4
      FROM table2
    INNER JOIN table3
      ON table2.column1 = table3.column1
)

因为我可以更好地阅读和分析 SQL。

于 2008-11-07T14:34:11.723 回答
1
SELECT
    Column1,
    Column2
FROM
    Table1
WHERE
    Column3 IN
    (
        SELECT TOP (1)
            Column4
        FROM 
            Table2
        INNER JOIN 
            Table3
        ON
            Table2.Column1 = Table3.Column1
    )
于 2011-01-03T05:56:03.267 回答
0

我通常做的是,

print("SELECT column1, column2
       FROM table1
       WHERE column3 IN (SELECT TOP(1) column4
                         FROM table2 INNER JOIN 
                              table3 ON table2.column1 = table3.column1)");
于 2008-11-07T14:31:41.477 回答
0

这是一个品味问题。

这是我的偏好。

SELECT 
  column1
 ,column2
FROM
  table1
WHERE column3 IN (
                 SELECT TOP(1) column4
                 FROM 
                   table2
                   INNER JOIN table3
                 ON table2.column1 = table3.column1
                 )
于 2008-11-07T14:44:21.607 回答
-4

这就是我们在这里的做法:

选择
        第 1 列,
        第 2 列,
        COLUMN5 = 'X' 时的情况
                        和
                        第 6 列 = 'Y'
                然后是“一个”
                当 COLUMN5 在 (
                                'AAA',
                                'BBB'
                        )
                然后是“两个”
                否则“三”
        以 COLUMN7 结尾
从
        表格1
在哪里
        第 2 列 (
                选择顶部(1)
                        第 4 栏
                从
                        表2
                        内部联接
                        表3
                                在
                                        表 2.COLUMN1 = 表 3.COLUMN1
                                        和
                                        表 2.COLUMN2
                                                之间
                                                        表 3.COLUMN2
                                                        和
                                                        表 3.COLUMN3
        )

我们的想法是:将 sql 关键字保持小写,并将所有变化的(因此“更有趣”)的东西(例如表或列名)都放在大写中。此处的代码可能看起来有点“夸张”,但如果您的复杂查询的名称(包括架构等)比本示例中的长得多,它会增加可读性。并且:根据对象的“级别”缩进所有对象。

于 2013-07-26T09:01:54.880 回答