SQL SELECT查询“向上移动一列1列”

时间:2011-10-20 06:53:35

标签: sql-server sql-server-2008

我有像这样的表

   value    updatedon   
    ------------------------------              
    1326    2011-10-18 00:06:00.000
    1327    2011-10-18 00:05:00.000
    1330    2011-10-18 00:03:00.000
    1331    2011-10-18 00:02:00.000
    1334    2011-10-18 00:01:00.000
    1333    2011-10-18 00:00:00.000

我希望结果像这样.....根据我们可以更新的时间 排序..你可以看到表结构非常清楚......

 changed        value   updatedon   
    ------------------------------------------              
    1327        1326    2011-10-18 00:06:00.000
    1330        1327    2011-10-18 00:05:00.000
    1331        1330    2011-10-18 00:03:00.000
    1334        1331    2011-10-18 00:02:00.000
    1333        1334    2011-10-18 00:01:00.000
    NULL        1333    2011-10-18 00:00:00.000

4 个答案:

答案 0 :(得分:2)

请检查以下代码

CREATE TABLE Test1 
(
    Col1  INT     ,
    TIME1 DATETIME
);

INSERT  INTO Test1 (Col1, Time1)
VALUES (1, GETDATE()), (2, GETDATE() + 1);

INSERT  INTO Test1 (Col1, Time1)
VALUES (3, GETDATE() + 2), (4, GETDATE() + 4);

SELECT * FROM Test1;

SELECT A.Col1, (SELECT TOP 1 Col1 AS 'Updated By'
FROM   Test1
WHERE  Time1 IN (SELECT MAX(Time1) AS 'Time1'
                 FROM   Test1
                 WHERE  Time1 < A.Time1)) AS 'Updated By' FROM Test1 AS A
ORDER BY Col1 DESC;

答案 1 :(得分:2)

CREATE TABLE TestData
(
     Value      INT NOT NULL
    ,UpdatedOn  DATETIME NOT NULL
);
INSERT  TestData 
SELECT 1326, '2011-10-18 00:06:00.000'
UNION ALL
SELECT 1327, '2011-10-18 00:05:00.000'
UNION ALL
SELECT 1330, '2011-10-18 00:03:00.000'
UNION ALL
SELECT 1331, '2011-10-18 00:02:00.000'
UNION ALL
SELECT 1334, '2011-10-18 00:01:00.000'
UNION ALL
SELECT 1333, '2011-10-18 00:00:00.000';

SELECT 'Solution 1';
WITH    CteRowNumber
AS
(
SELECT   a.Value
        ,a.UpdatedOn
        ,ROW_NUMBER() OVER(ORDER BY UpdatedOn DESC) RowNumber 
FROM    TestData a
)
SELECT   crt.Value  AS Changed
        ,prev.Value
        ,prev.UpdatedOn
FROM    CteRowNumber prev
LEFT JOIN CteRowNumber crt ON prev.RowNumber + 1 = crt.RowNumber

SELECT 'Solution 2';
DECLARE @Results TABLE
(
     Value      INT NOT NULL
    ,UpdatedOn  DATETIME NOT NULL
    ,RowNumber  INT PRIMARY KEY CLUSTERED
);
INSERT  @Results (Value, UpdatedOn, RowNumber)
SELECT   a.Value
        ,a.UpdatedOn
        ,ROW_NUMBER() OVER(ORDER BY UpdatedOn DESC) RowNumber 
FROM    TestData a;

SELECT   crt.Value  AS Changed
        ,prev.Value
        ,prev.UpdatedOn
FROM    @Results prev
LEFT JOIN @Results crt ON prev.RowNumber + 1 = crt.RowNumber

DROP TABLE TestData;

答案 2 :(得分:1)

create table #shift(
changed varchar(max),
[value] varchar(max),
updatedon datetime
)

declare @val varchar(max), @value varchar(max);
declare @up datetime, @updatedon datetime;
declare @count int;
set @count=1;

declare shift_cursor cursor for
select [value], updatedon from shift order by updatedon desc
open shift_cursor
fetch next from shift_cursor into @value,@updatedon
while(@@fetch_status=0)
begin
    if(@count=1)
    begin
        set @val=@value;
        set @up=@updatedon;
        set @count=@count+1;
        fetch next from shift_cursor into @value,@updatedon
    end
    insert into #shift values (@value,@val,@up);
    set @val=@value;
    set @up=@updatedon;
    fetch next from shift_cursor into @value,@updatedon 
end
insert into #shift values (null,@value,@updatedon);
select * from #shift;
close shift_cursor
deallocate shift_cursor
truncate table #shift

答案 3 :(得分:0)

我使用postgres完成这项任务。

select a.value, b.value as shiftedValue, a.updatedon from 
(select ROW_NUMBER() over (order by value,updatedon) as num,* from yourTable) as a
inner join
(select ROW_NUMBER() over (order by value,updatedon) as num,* from yourTable) as b
on a.num = b.num+1

请注意,第一行中有一个null