2010-01-06 115 views
6

當我編寫SQL查詢時,我發現自己經常會認爲「沒有辦法用單個查詢來做到這一點」。當發生這種情況時,我經常轉向存儲過程或使用臨時表(多種語言)的多語句表值函數,最後只需將結果合併並返回結果表即可。SQL查詢理論問題 - 單一語句與多語句查詢

我不知道是否有人知道,只是作爲一個理論問題,它是否應該可以編寫一個返回一個結果集爲一個單一的查詢(而不是多個語句)的任何查詢。顯然,我忽略了諸如代碼可讀性和可維護性等相關問題,甚至可能會查詢性能/效率。這更多的是關於理論 - 是否可以這樣做......並且不用擔心,我當然不打算在多語句更適合所有情況下適合我的目的時開始強迫自己寫單語句查詢,但是這可能會讓我思考是否有可行的方法從單個查詢中獲得結果的兩倍或更長一點。

我想幾個參數是爲了 - 我正在考慮關係數據庫(如MS SQL)與表遵循常見的最佳做法(如所有表具有主鍵等)。

注:(參考材料纖維網或類似的東西),以贏得「接受的答案」這一點,你需要提供明確的證據

+0

...或反例。 – 2010-01-06 19:16:19

+0

在您回答這個問題之前,您需要對「SQL理論」中的含義有更多的具體說明。實踐中使用的SQL在DBMS和DBMS版本之間有所不同。您需要標準化一組標準的SQL結構。例如,你允許什麼類型的子查詢?此外,您可能希望抽象出一些細節,例如最常用的「SQL查詢理論」,它使用關係演算或代數作爲SQL的抽象,將表格視爲行集,而不是有序的行列表。 – reinierpost 2011-04-29 13:38:56

回答

2

至少在最近的一個版本的Oracle中是絕對有可能的。它有一個使模型完整的「模型條款」。 (http://blog.schauderhaft.de/2009/06/18/building-a-turing-engine-in-oracle-sql-using-the-model-clause/)。當然,這都與通常的限制有關,我們並沒有無限的時間和記憶。

對於一個正常的sql方言沒有這些abdominations我不認爲這是可能的。

,我不能看到如何在「正常SQL」將實現一個任務: 假設一個表型整數

的單個列的每一行 「取值在當前行並返回多行,獲取該值,返回多行,然後繼續,直到連續兩次獲取相同的值,並將結果作爲結果返回。

+0

哇非常有趣...但是在我看來(如果我理解正確的話),雖然這是一個單獨的聲明,但它並不完全符合我的問題的精神,因爲您有能力迭代結果表。我想我正在更多地沿着「集合論」的思路思考。儘管如此,這實現了Turing-complete狀態,並且提到了大多數SQL(我認爲這意味着MSSQL)「可能不是」足以勝出,我想,即使我'米仍然不確定我的「真正」問題的最終答案是什麼。 – 2010-01-06 22:38:58

3

我相信這是可能的。我已經處理了非常困難的查詢,非常長的查詢,並且通常可以通過單個查詢來完成。但大多數情況下,更難以維護,所以如果您只使用一個查詢來完成,請確保您仔細評論您的查詢。

我從來沒有遇到過無法在單個查詢中完成的事情。
但有時最好在多個查詢中執行此操作。

+0

要添加一些信息:在我的工作中,我們有備份超過60的數據庫。我們使用非常大的表格和非常大的數據。 對於我們所做的工作類型,查詢可以執行多個頁面,因此通常最好執行多個查詢或使用工作表。 – 2010-01-06 18:46:51

+0

「querie做了很多頁面」是什麼意思? – 2010-01-06 18:59:44

+0

我的意思是說,當你把它寫在你的程序中(我用C++工作)時,你必須在查詢結束之前向下滾動很多頁面。 – 2010-01-07 16:45:37

2

我無法證明它,但我相信答案是謹慎的 - 只要你的數據庫設計正確完成。通常被迫編寫多個語句以獲得特定結果表明您的模式可能需要一些改進。

2

我會說「是」但無法證明它。然而,我的主要思維過程:

  • 任何選擇應該是基於集合操作

  • 你的假設是,你是在處理數學上正確設置(即正確標準化)

  • 集合論應保證其有可能

其他的想法:

  • 多個SELECT語句經常加載臨時表/表變量。這些可以在CTE中派生或分離。

  • 任何RBAR處理(好或壞)現在可以處理CROSS/OUTER應用到派生表

  • 的UDF會被歸類爲在這方面,我覺得「欺騙」,因爲它可以讓你把a。選擇到另一個模塊,而不是在你的單身一個

  • 任何寫在你的DML序列「之前」允許:這改變了從選擇狀態來選擇

  • 你有沒有在我們的商店看到一些代碼?

編輯,詞彙

編輯:適用於:作弊?

SELECT 
    * 
FROM 
    MyTable1 t1 
    CROSS APPLY 
    (
     SELECT * FROM MyTable2 t2 
     WHERE t1.something = t2.something 
    ) t2 
+0

什麼是rbar,cte和udf? – 2010-01-06 18:53:56

+0

我剛剛閱讀了'申請',這聽起來對我來說也是一種欺騙。它調用一個函數,它不是一個真正的SQL實體,而是在T-SQL中實現的,或者它所調用的任何函數。 – 2010-01-06 19:11:11

1

理論上是的,如果你使用外部應用程序或子查詢的函數或曲折的迷宮;然而,爲了可讀性和性能,我們總是以臨時表和多語句存儲過程結束。

上面有人評論道,這通常表明您的數據結構開始聞起來了;不是不好,,但是也許是出於性能原因(發生在我們身上)發生非規範化的時候,或者可能在規範化的「真實」數據前面放置一個非規範化查詢層。