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)