我有一个像下面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