Форматирование Четкие и читаемые SQL-запросы
Я пишу некоторые SQL-запросы с несколькими подзапросами и множеством объединений везде, как внутри подзапроса, так и в результате таблицы из подзапроса.
Мы не используем представления, чтобы не возникало вопросов.
После написания я смотрю на это и почесываю голову, думая, что это даже делает, потому что я не могу следовать за ней.
Какое форматирование вы используете, чтобы попытаться очистить такой беспорядок? Возможно, отступы?
Ответы
Ответ 1
С большими запросами я склонен много полагаться на именованные результирующие наборы, используя WITH
. Это позволяет заранее определить набор результатов и упростить основной запрос. Именованные наборы результатов могут помочь сделать план запроса более эффективным, например, postgres сохраняет результирующий набор во временной таблице.
Пример:
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)
Пример немного ухищрен, но я надеюсь, что это показывает увеличение ясности по сравнению с встроенными подзапросами. Именованные результирующие наборы очень помогли мне, когда я готовил данные для использования OLAP. Именованные наборы результатов также необходимы, если у вас есть/хотите создавать рекурсивные запросы.
WITH
работает по крайней мере в текущих версиях Postgres, Oracle и SQL Server
Ответ 2
Мальчик - это загруженный вопрос.:) Есть так много способов сделать это правильно, поскольку на этом сайте есть умные люди. Тем не менее, вот как я держу себя в здравом уме при построении сложных операторов sql:
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
Если вам интересно, я могу отправлять/отправлять макеты для вставок, обновлений и удалений, а также коррелированные подзапросы и сложные предикаты соединения.
Отвечает ли это на ваш вопрос?
Ответ 3
Табличные псевдонимы и простая согласованность помогут вам долго и долго.
Что выглядит прилично - это разбить строки на ключевые слова SELECT, FROM, WHERE (и т.д.).
Совпадения могут быть более сложными, отступая от части ON, соединяющей основную часть ее с фронтом.
Также помогает помощь сложным логическим выражениям (объединениям и условиям условий) на одном уровне.
Отступы логически совпадают с уровнем оператора (подзапросы, открывающие скобки и т.д.)
Используйте все ключевые слова и стандартные функции.
Действительно сложный SQL не будет уклоняться от комментариев - хотя обычно вы находите их в сценариях SQL, а не динамическом SQL.
Пример 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'
Итак, в конце, чтобы подвести итог, наиболее важна последовательность.
Ответ 4
Как правило, люди разрывают строки на зарезервированных словах и отбрасывают любые подзапросы:
SELECT *
FROM tablename
WHERE value in
(SELECT *
FROM tablename2
WHERE condition)
ORDER BY column
Ответ 5
В общем, я следую простому иерархическому набору правил форматирования. В основном, ключевые слова, такие как SELECT, FROM, ORDER BY, все идут по своей линии. Каждое поле идет по собственной линии (рекурсивным образом)
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
)
Ответ 6
Мне нравится использовать что-то вроде:
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
Ответ 7
только правильный и правильный способ форматирования SQL:
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
;
;)
Серьезно, хотя мне нравится использовать предложения WITH (как уже было предложено), чтобы приручить очень сложные SQL-запросы.
Ответ 8
Поместите его в представление, чтобы было легче визуализировать, возможно, сохранить снимок экрана как часть документации. Вам не нужно сохранять представление или использовать его для каких-либо других целей.
Ответ 9
Отступ, конечно, но вы также можете разбить подзапросы с комментариями, сделать имена псевдонимов действительно значимыми и указать, какой подзапрос они ссылаются, например. innerCustomer, внешнийклиент.
Общие выражения таблицы могут действительно помочь в некоторых случаях разбить запрос на значимые разделы.
Ответ 10
Вековой вопрос с тысячей мнений и ни один правильный ответ, и один из моих фаворитов. Здесь мои два цента.
Что касается подзапросов, то в последнее время мне стало легче следить за тем, что происходит с "крайним" отступом и добавлением комментариев следующим образом:
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
Что касается другого цента, я использую только верхний регистр для первого слова. Со страницами запросов на запуск он немного упрощает выбор, когда начинается новый.
Ваш пробег, конечно, будет меняться.
Ответ 11
Ничего себе, много ответов здесь, но одна вещь, которую я не видел во многих, - это КОММЕНТАРИИ! Я обычно добавляю много комментариев, особенно с большими операторами SQL. Форматирование важно, но хорошо сделанные и содержательные комментарии чрезвычайно важны не только для вас, но и для бедной души, которым необходимо поддерживать код;)