我正在編寫一些SQL查詢,其中包含子查詢和子查詢結果表中的幾個子查詢和大量連接。格式化清晰可讀的SQL查詢
我們沒有使用視圖,所以這是不可能的。
寫完後,我正在看它,抓着我的腦袋想知道它甚至在做什麼,因爲我無法遵循它。
你用什麼樣的格式來嘗試清理這樣的混亂?縮進也許?
我正在編寫一些SQL查詢,其中包含子查詢和子查詢結果表中的幾個子查詢和大量連接。格式化清晰可讀的SQL查詢
我們沒有使用視圖,所以這是不可能的。
寫完後,我正在看它,抓着我的腦袋想知道它甚至在做什麼,因爲我無法遵循它。
你用什麼樣的格式來嘗試清理這樣的混亂?縮進也許?
對於大量查詢,我傾向於使用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
WITH關鍵字很有趣。絕對可以讓代碼更加清潔,因爲我可以在隨後的行中引用名稱的結果集。 – MxyL 2011-03-28 16:33:52
一般來說,人們打破保留字線,並縮進任何子查詢:
SELECT *
FROM tablename
WHERE value in
(SELECT *
FROM tablename2
WHERE condition)
ORDER BY column
表的別名和簡單的一致性,將讓你很長,很長的路要走
看起來體面的斷裂線在主要關鍵字SELECT,FROM,WHERE(等..)。
連接可能會更棘手,縮進連接的ON部分將其重要部分帶到前面。
在同一級別上打破複雜的邏輯表達式(連接和條件)都有幫助。
縮進邏輯語句的同一級別(子查詢,打開支架等)
大寫的所有關鍵字和標準功能。
真正複雜的SQL不會迴避評論 - 儘管通常您可以在SQL腳本中找到這些不是動態SQL。
編輯例如:
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'
所以,在最後總結一下 - 一致性纔是最重要的。
將它放在一個視圖中,這樣可以更容易直觀化,也可以將屏幕截圖保留爲文檔的一部分。您不必保存視圖或將其用於任何其他目的。
一般來說,我遵循一個簡單的分層格式設置規則。基本上,諸如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
)
我喜歡用這樣的:肯定
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
縮進,但你也可以分割子查詢了評論,讓您的別名命名真正有意義的東西並指定它們引用的子查詢,例如innerCustomer,outerCustomer。
公用表表達式在某些情況下可以幫助將查詢分解爲有意義的部分。
一個古老的問題的當前版本有一千個判斷,沒有一個正確的答案,和我的最愛之一。這是我的兩分錢。
至於子查詢,最近我發現更容易按照發生了什麼事與「極端」縮進和添加像這樣的評論:
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
至於其他的分,我只用大寫在第一個字上。通過運行查詢頁面,可以在新文件啓動時輕鬆選擇。
當然,您的里程會有所不同。
男孩是這是一個加載的問題。 :)有很多方法可以做到這一點,因爲這個網站上有聰明的人。這就是說,這裏是我如何使自己保持清醒構建複雜的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
如果你有興趣,我可以張貼/發送的插入,更新佈局和刪除以及相關子查詢和複雜的連接謂詞。
這是回答您的問題嗎?
的只有真實和正確的格式化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
;
;)
雖然嚴重,我想與條款使用(如已經建議)馴服非常複雜的SQL查詢。
哇,在這裏有很多的迴應,但有一件事我沒有看到很多是評論!我傾向於在整個過程中添加很多評論,尤其是對於大型SQL語句。格式是重要的,但很好的地位和有意義的評論是非常重要的,不只是爲你,而是可憐的靈魂誰需要維護代碼;)
什麼平臺?有SSMS和MySQL Workbench的插件可以爲你「美化」你的SQL代碼。 – 2011-03-28 15:41:40
好問題。我還沒有爲SQL自己找到一個令人信服的格式化規則。 – 2011-03-28 15:42:25
@Brian Driscoll,你知道MySQL Workbench的插件嗎? – dcarneiro 2011-03-28 15:45:12