Хорошая практика использования отступов в операторах SQL [закрыто]

StackOverflow https://stackoverflow.com/questions/272210

  •  07-07-2019
  •  | 
  •  

Вопрос

Какова общепринятая практика создания отступов в SQL-операторах?Например, рассмотрим следующий оператор SQL:

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
)

Мне нравится иметь все ", "впереди, таким образом, я никогда не ищу их при появлении ошибки в строке X из редактора SQL.


Это пример для тех, кто не использует этот тип записи 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
(
    ...
)

В первом примере мне показалось проще и быстрее.Надеюсь, этот пример лучше покажет вам мою точку зрения.

Другие советы

SELECT column1, column2
FROM table
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 
    )

Мне нравится иметь "реки" пустого пространства в коде. Это немного облегчает сканирование.

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

Мне нравится, как Джалберт выстраивает ключевые слова справа от себя. Я также хотел бы добавить, что мне нравятся AND и OR слева (некоторые люди ставят их справа). Кроме того, мне нравится выстраивать мои знаки равенства, когда это возможно.


SELECT column1, 
       column2  
  FROM table1, table2 
 WHERE table1.column1 = table2.column4 
   AND table1.col5    = "hi" 
    OR table2.myfield = 678 

Это мой личный метод. В зависимости от длины условия соединения я иногда делаю отступ в строке ниже.

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
  )

Я написал кодовый стандарт для нашего магазина, который предельно смещен в сторону читабельности / «открываемости». (последний в первую очередь полезен в операторах вставки-выбора):

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.

Если у вас есть длинная инструкция SQL, которую вы хотите переформатировать без всякого набора текста и табуляции, вы можете добавить ее в этого веб-сайта и получите красиво отформатированный результат. Вы можете поэкспериментировать с различными форматами, чтобы увидеть, что делает ваш текст наиболее читабельным.

Изменить. Я считаю, что это является местоположением средства форматирования SQL в 2014 году.

Форматирование SQL - это область, в которой существует много расхождений и разногласий...Но, черт возьми, мне нравится сосредотачиваться на удобочитаемости и думать, что, что бы вы ни делали, последовательное соблюдение любых правил, снижающих удобочитаемость, является, как гласит старое клише, "глупой последовательностью" ( "Глупая последовательность - это хобби для простых умов").

Итак, вместо того чтобы называть их правилами, вот несколько рекомендаций.Для каждого основного предложения в инструкции SQL (Select, Insert, Delete, From, Where, Having, Group BY, Order By, ...Возможно, я упускаю несколько) должны быть ЛЕГКО идентифицируемы.Поэтому я обычно размещаю их с отступами на самом высоком уровне, все вровень друг с другом.Затем внутри каждого предложения я равномерно делаю отступ для следующей логической подструктуры...и так далее..Но я не стесняюсь (и часто делаю) изменять шаблон, если в каком-либо отдельном случае это было бы более читабельно...Хорошим примером являются сложные операторы Case.Поскольку все, что требует горизонтальной прокрутки, значительно снижает читаемость, я часто пишу сложные (вложенные) регистровые выражения в нескольких строках.Когда я это делаю, я стараюсь оставить в начале такого оператора висячий отступ, основанный на его логическом месте в инструкции SQL, и делаю отступ в остальных строках инструкции на несколько символов дальше...

Код базы данных SQL существует уже давно, еще до того, как компьютеры начали использовать нижний регистр, поэтому исторически предпочтение отдавалось ключевым словам в верхнем регистре, но я предпочитаю удобство чтения традициям...(и каждый инструмент, который я использую, теперь все равно кодирует ключевые слова цветом)

Я бы также использовал псевдонимы таблиц, чтобы уменьшить объем текста, который приходится сканировать глазу, чтобы понять структуру запроса, при условии, что псевдонимы не создают путаницы.В запросе, содержащем менее 3 или 4 таблиц, подойдут односимвольные псевдонимы, я часто использую первую букву таблицы, если все таблицы начинаются с другой буквы...опять же, все, что больше всего способствует удобочитаемости.Наконец, если ваша база данных поддерживает это, многие ключевые слова являются необязательными (например, "Внутренний", "Внешний", "Как" для псевдонимов и т.д.) "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)

Отформатируйте код любым способом, который сделает его наиболее читаемым...

Мне нравится, когда разные части моего запроса располагаются вертикально. Я имею тенденцию использовать размер табуляции 8 пробелов для SQL, который, кажется, работает хорошо.

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

Пример отступа для очень очень очень сложного 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

Поскольку большинство из приведенных выше выровняло имена возвращаемых столбцов, я считаю, что выстраивание имен и условий таблиц значительно улучшает читабельность.

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
    )

Вот мой взгляд на это:

select column1, column2
    from table1
    where (column3 in (
        select top(1) column4
            from table2
            inner join table3
                on (table2.column1 = table3.column1)
    ))
;
  • Все в нижнем регистре, потому что строчные символы легче читать (и у нас есть подсветка кода, чтобы подчеркнуть ключевые слова), а также их легче вводить
  • Каждое ограничение или параметр для ключевого слова (например, from при выборе или on при соединении) имеет отступ, чтобы показать их зависимость от ключевого слова outward
  • Закрывающая скобка находится на том же уровне отступа, что и открывающая , где
  • Используйте квадратные скобки для предложений where и on, чтобы повысить удобочитаемость
  • Поставьте точку с запятой, закрывающую оператор select, с одинаковым отступом, чтобы можно было лучше различать несколько операторов (если вам нужна точка с запятой в вашем языке, как это делает SAS PROC SQL)
  • Он по-прежнему довольно компактный и не растягивается по всей странице

Конечно, это сводится к личным предпочтениям. И если в условиях команды, это то, что должно быть согласовано между членами ради последовательности. Но это было бы моим предпочтением:

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)

или как это:

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
....)

Несмотря на то, что stackoverflow портит форматирование с дополнительным начальным пробелом, я поставил несколько периодов, чтобы вы могли увидеть фактическое форматирование ...

Я только что пропустил его через мой prettifier 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.

Да, это довольно субъективно...Но вот мои 2 цента:

SELECT
   Column1,
   Column2
FROM Table1
WHERE 
   Column3 IN (
      SELECT Column4
      FROM Table2
      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

По сути, мои правила таковы:

  • Ключевые слова с заглавной буквы
  • Столбцы располагаются в отдельных строках, но ВЫБРАННЫЕ модификаторы (ВЫБЕРИТЕ TOP 100, ВЫБЕРИТЕ DISTINCT и т.д.) Или отдельные столбцы (ВЫБЕРИТЕ 1, ВЫБЕРИТЕ Id, ВЫБЕРИТЕ * и т.д.) Располагаются в одной строке
  • Условия объединения с отступом под предложением JOIN
  • Используйте JOIN для ВНУТРЕННЕГО СОЕДИНЕНИЯ (поскольку оно является общим) и полностью укажите другие (ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ и т.д.)
  • Откройте parens в той же строке, закройте paren в отдельной строке.Если у вас есть псевдоним, то псевдоним идет с close paren .

Эта ссылка - лучшая, которую я нашел. http://www.sqlinform.com/free_online_sw.html

Ну, конечно, это зависит от запроса.

Для простых запросов очень формальная схема отступов - это просто больше проблем, чем стоит, и она может сделать код менее читаемым, а не больше. Но по мере роста сложности вам нужно начать более осторожно разбираться в том, как вы структурируете оператор, чтобы быть уверенным, что он будет читаться позже.

Я не знаю, есть ли стандарт, но мне нравится делать это таким образом;

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

потому что я могу лучше читать и анализировать SQL.

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

Что я обычно делаю, так это

print("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
                 )

Вот как мы это сделаем здесь:

select
        COLUMN1,
        COLUMN2,
        case    when    COLUMN5 = 'X'
                        and
                        COLUMN6 = 'Y'
                then    'one'
                when    COLUMN5 in (
                                'AAA',
                                'BBB'
                        )
                then    'two'
                else    'three'
        end as COLUMN7
from
        TABLE1
where
        COLUMN2 in (
                select top(1)
                        COLUMN4
                from
                        TABLE2
                        inner join
                        TABLE3
                                on
                                        TABLE2.COLUMN1 = TABLE3.COLUMN1
                                        and
                                        TABLE2.COLUMN2
                                                between
                                                        TABLE3.COLUMN2
                                                        and
                                                        TABLE3.COLUMN3
        )

Наша идея состоит в том, чтобы сохранить ключевые слова sql в нижнем регистре и поместить все изменяющиеся (и, следовательно, «более интересные») вещи, такие как имена таблиц или столбцов, в верхний регистр. Код может выглядеть немного «взорванным» здесь, но это повышает удобочитаемость, если у вас есть сложные запросы с более длинными именами (включая схему и т. д.) намного дольше, чем в этом примере. И: сделать отступ для всех объектов в соответствии с их «уровнем».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top