我有一個像下面SQL嵌套查詢
id name dependency
-----------------------
1 xxxx 0
2 yyyy 1
3 zzzz 2
4 aaaaaa 0
5 bbbbbb 4
6 cccccc 5
不勝枚舉的表。我想從該表中選擇一組行,方法是在SQL的where子句中給出0依賴項的名稱,直到它達到不存在更多依賴關係的條件。 (例如行1,2和3形成一個組,行4,5,6是另一個組)。請幫助
我有一個像下面SQL嵌套查詢
id name dependency
-----------------------
1 xxxx 0
2 yyyy 1
3 zzzz 2
4 aaaaaa 0
5 bbbbbb 4
6 cccccc 5
不勝枚舉的表。我想從該表中選擇一組行,方法是在SQL的where子句中給出0依賴項的名稱,直到它達到不存在更多依賴關係的條件。 (例如行1,2和3形成一個組,行4,5,6是另一個組)。請幫助
聽起來像你想遞歸查詢你的表,爲此你需要一個公共表表達(CTE)
This MSDN article很好地解釋了CTE。起初他們感到困惑,但卻很容易實現。
順便說一句,這顯然只適用於SQL Server,我不知道你會如何在MySQL中實現。
這是首先想到的東西。它可能會更直接/簡潔地完成,我會盡量詳細地討論一下。
SELECT *
FROM table T1
WHERE T1.id >=
(SELECT T2.id FROM table T2 WHERE T2.name = '---NAME HERE---')
AND T1.id <
(SELECT MIN(id)
FROM table T3
WHERE T3.dependency = 0 AND T3.id > T2.id)
你只想選擇名稱的組有問題屬於,對不對? – 2011-04-19 04:29:26
由於您沒有指定產品,我將使用SQL規範中提供的功能。在這種情況下,我使用的是由許多數據庫產品包括SQL Server 2005+和Oracle(但不是MySQL的)支持的公共表表達式:
With MyDependents As
(
Select id, name, 0 As level
From MyTable
Where dependency = 0
And name = 'some value'
Union All
Select T.id, T.name, T.Level + 1
From MyDependents As D
Join MyTable As T
On T.id = D.dependency
)
Select id, name, level
From MyDependents
它不依賴於普通表另一個解決方案表達式,但不承擔深度的最高水平(在這種情況下低於0級兩個級別)會像
Select T1.id, T1.name, 0 As level
From MyTable As T1
Where T1.name = 'some value'
Union All
Select T2.id, T2.name, 1
From MyTable As T1
Join MyTable As T2
On T2.Id = T1.Dependency
Where T1.name = 'some value'
Union All
Select T3.id, T3.name, 2
From MyTable As T1
Join MyTable As T2
On T2.Id = T1.Dependency
Join MyTable As T3
On T3.Id = T2.Dependency
Where T1.name = 'some value'
您可能想要使用所有主要SQL方言中常用的功能,而不是像CTE那樣的高級功能,即使在標準中也是如此。例如,這在MySQL中不起作用,可能是這裏最常見的平臺。 – dkretz 2011-04-19 04:44:23
@le dorfier - 首先,作爲一個小小的咆哮,我討厭這個唯一的SQL標籤。其次,有人可能會爭辯說,大多數主要的SQL方言都支持CTE。 Oracle,SQL Server,Informix,DB2,Postgres。在這個階段支持CTE的數量要多於沒有。不過,是的,MySQL是唯一的例外。第三,我不同意MySQL是最常見的平臺。我會說SQL Server比MySQL更常見。 – Thomas 2011-04-19 04:48:43
@le dorfier - 儘管如此,我還是增加了關於MySQL的免責聲明。 – Thomas 2011-04-19 04:50:46
如果你能估計最大深度,該工程以類似:
SELECT
COALESCE(t4.field1, t3.field1, t2.field1, t1.field1, t.field1),
COALESCE(t4.field2, t3.field2, t2.field2, t1.field2, t.field2),
COALESCE(t4.field3, t3.field3, t2.field3, t1.field3, t.field3),
....
FROM table AS t
LEFT JOIN table AS t1 ON t.dependency = t1.id
LEFT JOIN table AS t2 ON t1.dependency = t2.id
LEFT JOIN table AS t3 ON t2.dependency = t3.id
LEFT JOIN table AS t4 ON t3.dependency = t4.id
....
這是一個瘋狂的猜測,只是爲了不同,但我認爲它有點漂亮,無論如何。至少與其他任何人一樣便攜。但我不想仔細看看;我想使用明智的數據,開始測試,並檢查明智的結果。
SELECT *
FROM your_table
START WITH id = :id_of_group_header_row
CONNECT BY dependency = PRIOR id
查詢是這樣的:
選擇滿足START WITH
條件的所有行(該行是根現在)
2.選擇所有的行滿足CONNECT BY
條件,
關鍵字PRIOR
表示此列的值將會可以從根行
考慮採取步驟2中選擇行是根
4.轉到步驟2,直到沒有更多的行
謝謝亞歷山大。這qry是匹配我的需要。 – Deborah 2011-04-19 09:03:01
@Deborah:隨時接受和投票我的帖子:) – 2011-04-19 09:07:17
如果你真的想要一個答案,你一定要告訴我們使用您正在使用的數據庫產品和版本。是否可以使用SQL語言的任何ISO規範中列出的任何功能與您在使用的數據庫產品中是否可行有很大不同。 – Thomas 2011-04-19 04:34:37
除非我錯過了一些東西,這並不需要超出基本的東西。如果name的參數是'xxxx',她希望行有w/id 1-3 – 2011-04-19 04:36:18
謝謝大家!我有我的需要見面。 – Deborah 2011-04-19 09:06:25