Sql server MsSQL以ZicZac方式基于先前值和当前值获取数据
我的桌子坏了Sql server MsSQL以ZicZac方式基于先前值和当前值获取数据,sql-server,Sql Server,我的桌子坏了 ---------------------------------------------------------- |RunningId PreviousValue CurrentValue CreatedDate | ---------------------------------------------------------- |1 1000 1001 2018-04-20 | ----------------
----------------------------------------------------------
|RunningId PreviousValue CurrentValue CreatedDate |
----------------------------------------------------------
|1 1000 1001 2018-04-20 |
----------------------------------------------------------
|2 1001 1002 2018-04-21 |
----------------------------------------------------------
|3 1002 1003 2018-04-22 |
----------------------------------------------------------
|4 2000 2003 2018-04-22 |
----------------------------------------------------------
|5 2003 2004 2018-04-23 |
----------------------------------------------------------
如果我搜索1002,查询应该从开头返回上一个值和当前值
例如:
我想以ZicZac的方式引用。如果我搜索1000、1001、1002、1003,所有结果都应该返回第1、2和3行。
同样,如果我搜索2000、2003、2004,它应该返回第4、5行。这些值是随机的。不按顺序。
第一行在开头有一些值,然后它更改为其他值,然后更改为其他值,依此类推。所以这对可以是[pre cur value],1-3,3-7,7-2,2-100。。。。如果我搜索7,它应该返回双向1,3,7,2100
如何查询此项?您可以使用下面的代码从表中获取1002之前的所有值,假设您想从头开始
select Prevalue, CurrentValue
FROM MyTable
WHERE id <=
(SELECT Id from MyTable
WHERE PreValue = 1002)
ORDER BY id
您还可以使用row_number函数来获得所需的结果
create table t (RunningId int,PreviousValue int,CurrentValue int,CreatedDate date)
;
insert into t values
(1, 1000, 1001, '04-20-2018')
,(2, 1001, 1002, '04-21-2018')
,(3, 1002, 1003, '04-22-2018')
,(4, 2000, 2003, '04-22-2018')
,(5, 2003, 2004, '04-23-2018');
; with cte as (
select *,r=row_number() over (order by runningid asc) from
t
)
select c1.* from cte c1 join cte
c2 on c1.r<=c2.r and c2.previousvalue=1002
另外,如果您的RunningId值总是在增加,那么您不需要行号,简单的自连接将如下所示
select t1.*
from t t1
join t t2
on t1.RunningId<=t2.RunningId and t2.previousvalue=1002
这会解决你的问题
select Prevalue, CurrentValue FROM Table1 WHERE Prevalue = 1002 or
CurrentValue = 1002 or CurrentValue = (Select Prevalue from Table1
where CurrentValue = 1002 ) ORDER BY id
尝试使用此递归查询。它可以优化一点,但会给你如何链接每一个关系的基本想法
DECLARE @ValueToFind INT = 1002
;WITH ForwardRelationships AS
(
SELECT
SourceValue = @ValueToFind,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
IDs AS I
WHERE
I.CurrentValue = @ValueToFind OR I.PreviousValue = @ValueToFind
UNION ALL
SELECT
SourceValue = F.SourceValue,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
ForwardRelationships AS F -- We are referencing the CTE that we are declaring (recursively)
INNER JOIN IDs AS I ON F.CurrentValue = I.PreviousValue
),
BackwardRelationships AS
(
SELECT
SourceValue = @ValueToFind,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
IDs AS I
WHERE
I.CurrentValue = @ValueToFind OR I.PreviousValue = @ValueToFind
UNION ALL
SELECT
SourceValue = F.SourceValue,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
BackwardRelationships AS F
INNER JOIN IDs AS I ON F.PreviousValue = I.CurrentValue
)
SELECT
F.PreviousValue,
F.CurrentValue
FROM
ForwardRelationships AS F
UNION
SELECT
B.PreviousValue,
B.CurrentValue
FROM
BackwardRelationships AS B
OPTION
(MAXRECURSION 30000)
使用递归CTE。谢谢Ravi。它适用于1002,但不适用于1003。我想以ZicZac的方式引用。如果我搜索100110003,所有结果都应该返回第1、2和3行。同样,如果我搜索2001,它应该返回第4、5行。这些值是随机的。不按顺序。第一行在开头有一些值,然后它更改为其他值,然后更改为其他值,依此类推。所以这对可以是[pre cur value],1-3,3-7,7-2,2-100。。。。如果我搜索7,它应该返回双向1,3,7,2100。我明白了吗?谢谢Dhruv,谢谢Ravi。它适用于1002,但不适用于1003。我想以ZicZac的方式引用。如果我搜索100110003,所有结果都应该返回第1、2和3行。同样,如果我搜索2001,它应该返回第4、5行。这些值是随机的。不按顺序。第一行在开头有一些值,然后它更改为其他值,然后更改为其他值,依此类推。所以这对可以是[pre cur value],1-3,3-7,7-2,2-100。。。。如果我搜索7,它应该返回双向1,3,7,2100。在这里,我可以使用runningId和Date进行排序。我清楚了吗?Dhruvu,CTE为10011002工作,而不是为1003工作。它为示例场景工作,将实时尝试,如果需要任何帮助,请回复。非常感谢埃兹洛。。。。
DECLARE @ValueToFind INT = 1002
;WITH ForwardRelationships AS
(
SELECT
SourceValue = @ValueToFind,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
IDs AS I
WHERE
I.CurrentValue = @ValueToFind OR I.PreviousValue = @ValueToFind
UNION ALL
SELECT
SourceValue = F.SourceValue,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
ForwardRelationships AS F -- We are referencing the CTE that we are declaring (recursively)
INNER JOIN IDs AS I ON F.CurrentValue = I.PreviousValue
),
BackwardRelationships AS
(
SELECT
SourceValue = @ValueToFind,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
IDs AS I
WHERE
I.CurrentValue = @ValueToFind OR I.PreviousValue = @ValueToFind
UNION ALL
SELECT
SourceValue = F.SourceValue,
CurrentValue = I.CurrentValue,
PreviousValue = I.PreviousValue
FROM
BackwardRelationships AS F
INNER JOIN IDs AS I ON F.PreviousValue = I.CurrentValue
)
SELECT
F.PreviousValue,
F.CurrentValue
FROM
ForwardRelationships AS F
UNION
SELECT
B.PreviousValue,
B.CurrentValue
FROM
BackwardRelationships AS B
OPTION
(MAXRECURSION 30000)