MsSQL以ZicZac方式基于上一个和当前值获取数据

时间:2018-06-20 08:47:38

标签: sql-server

我的桌子有

----------------------------------------------------------
|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,则查询应从开头开始返回上一个和当前值 例如:

----------------------------------------------------------
PreValue   CurrrentValue:
----------------------------------------------------------
1000       1001
----------------------------------------------------------
1001       1002
----------------------------------------------------------
1002       1003
----------------------------------------------------------

我想以ZicZac的方式进行参考。如果我搜索1000、1001、1002、1003,则所有结果应返回行#1,2和3。 如果我搜索2000、2003、2004,同样的方法,它应该返回行#4,5。值是随机的。不按顺序。 第一行的开头有一些值,然后更改为其他值,然后更改为其他值,依此类推。因此Pair可以是[pre-cur value],1-3、3-7、7-2、2-100 ....如果我搜索7,则应该同时返回1,3,7,2,100

如何查询?

4 个答案:

答案 0 :(得分:1)

这将解决您的问题

select Prevalue, CurrentValue FROM Table1 WHERE Prevalue = 1002 or
CurrentValue = 1002 or  CurrentValue = (Select Prevalue  from Table1
where CurrentValue = 1002 ) ORDER BY id

答案 1 :(得分:0)

您可以使用下面的代码从表中获取1002之前的所有值,前提是您希望从头开始。

select Prevalue, CurrentValue
FROM MyTable
WHERE id <=
(SELECT Id from MyTable 
WHERE PreValue = 1002)
ORDER BY id

答案 2 :(得分:0)

您还可以使用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值始终在增加,则不需要row_number,简单的自连接将按以下方式工作

select t1.*
from t t1
join t t2 
on t1.RunningId<=t2.RunningId and t2.previousvalue=1002

答案 3 :(得分:0)

尝试使用此递归查询。可以对其进行一些优化,但是将为您提供如何链接每个关系的基本概念。

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)