基于列中的值对SQL查询进行排序,确定下一行中另一列的值
我的桌子看起来像这样:基于列中的值对SQL查询进行排序,确定下一行中另一列的值,sql,sql-server-2008,sql-order-by,Sql,Sql Server 2008,Sql Order By,我的桌子看起来像这样: Value Previous Next 37 NULL 42 42 37 3 3 42 79 79 3 NULL 除了,桌子都坏了。(没有重复项,所以这不是问题。)我想知道是否有任何方法可以进行查询,对输出进行排序,基本上是说“下一行‘value’=这一行‘Next’”,如上所示 我无法控制数据库以及这些数据的存储方式。
Value Previous Next
37 NULL 42
42 37 3
3 42 79
79 3 NULL
除了,桌子都坏了。(没有重复项,所以这不是问题。)我想知道是否有任何方法可以进行查询,对输出进行排序,基本上是说“下一行‘value’=这一行‘Next’”,如上所示
我无法控制数据库以及这些数据的存储方式。我只是想找回它并组织它。SQL Server我相信是2008年
我意识到这在以后进行重组并不困难,但我只是想知道是否可以编写一个查询,这样我就不用担心了。类似的方法应该可以:
With Parent As (
Select
Value,
Previous,
Next
From
table
Where
Previous Is Null
Union All
Select
t.Value,
t.Previous,
t.Next
From
table t
Inner Join
Parent
On Parent.Next = t.Value
)
Select
*
From
Parent
类似的方法应该会奏效:
With Parent As (
Select
Value,
Previous,
Next
From
table
Where
Previous Is Null
Union All
Select
t.Value,
t.Previous,
t.Next
From
table t
Inner Join
Parent
On Parent.Next = t.Value
)
Select
*
From
Parent
如果您使用的是
Oracle
,请尝试以-connectby开始
select ... start with initial-condition connect by
nocycle recursive-condition;
编辑:对于SQL Server,使用和语法,如下所示:
WITH rec(value, previous, next) AS
(SELECT value, previous, next
FROM table1
WHERE previous is null
UNION ALL
SELECT nextRec.value, nextRec.previous, nextRec.next
FROM table1 as nextRec, rec
WHERE rec.next = nextRec.value)
SELECT value, previous, next FROM rec;
如果您使用的是Oracle
,请尝试以-connectby开始
select ... start with initial-condition connect by
nocycle recursive-condition;
编辑:对于SQL Server,使用和语法,如下所示:
WITH rec(value, previous, next) AS
(SELECT value, previous, next
FROM table1
WHERE previous is null
UNION ALL
SELECT nextRec.value, nextRec.previous, nextRec.next
FROM table1 as nextRec, rec
WHERE rec.next = nextRec.value)
SELECT value, previous, next FROM rec;
一种方法是使用联接:
select t.*
from t left outer join
t tnext
on t.next = tnext.val
order by tnext.value
然而,这不就行了吗
select t.*
from t
order by t.next
一种方法是使用联接:
select t.*
from t left outer join
t tnext
on t.next = tnext.val
order by tnext.value
然而,这不就行了吗
select t.*
from t
order by t.next
使用a,使用此处的“一个i”列表,您可以在链接列表中有多个路径:
with cte (Value, Previous, Next, Level)
as
(
select Value, Previous, Next, 0 as Level
from data
where Previous is null
union all
select d.Value, d.Previous, d.Next, Level + 1
from data d
inner join cte c on d.Previous = c.Value
)
select * from cte
使用a,使用此处的“一个i”列表,您可以在链接列表中有多个路径:
with cte (Value, Previous, Next, Level)
as
(
select Value, Previous, Next, 0 as Level
from data
where Previous is null
union all
select d.Value, d.Previous, d.Next, Level + 1
from data d
inner join cte c on d.Previous = c.Value
)
select * from cte
这应该可以满足您的需要:
WITH CTE AS (
SELECT YourTable.*, 0 Depth
FROM YourTable
WHERE Previous IS NULL
UNION ALL
SELECT YourTable.*, Depth + 1
FROM YourTable JOIN CTE
ON YourTable.Value = CTE.Next
)
SELECT * FROM CTE
ORDER BY Depth;
(为了简洁起见,省略了引用完整性和索引。)
我们使用递归公共表表达式(CTE
)从列表的开头(其中Previous为NULL
)移动到后面的节点(,在您的表上。Value=CTE.Next
),同时记住到达当前节点所需的递归深度(在深度中)
最后,我们只需按到达每个节点所需的递归深度排序(按深度排序)。这应该满足您的需要:
WITH CTE AS (
SELECT YourTable.*, 0 Depth
FROM YourTable
WHERE Previous IS NULL
UNION ALL
SELECT YourTable.*, Depth + 1
FROM YourTable JOIN CTE
ON YourTable.Value = CTE.Next
)
SELECT * FROM CTE
ORDER BY Depth;
(为了简洁起见,省略了引用完整性和索引。)
我们使用递归公共表表达式(CTE
)从列表的开头(其中Previous为NULL
)移动到后面的节点(,在您的表上。Value=CTE.Next
),同时记住到达当前节点所需的递归深度(在深度中)
最后,我们只需按到达每个节点所需的递归深度排序(按深度排序)。我不认为这是op想要的。您基本上是按照next
值的升序对行进行排序,op希望按问题中显示的顺序对行进行排序。我不认为这是op想要的。您基本上是按照next
值的升序对行进行排序,op希望按问题中所示的顺序对行进行排序。您能给出一个您想要的输入和输出示例吗?不清楚你在寻找什么。你能举一个你想要的输入和输出的例子吗?不清楚您在寻找什么。谢谢您的回答,效果很好,也谢谢您的解释!:)还感谢所有其他回答的人。谢谢你的回答,它非常有效,也感谢你的解释!:)还要感谢所有其他回答的人。