您如何订购一组记录,然后插入他们的订单?

时间:2013-10-15 14:38:52

标签: sql sql-server tsql

我有一个包含ID和TIMESTAMP的日志表。我想ORDER BY ID然后是TIMESTAMP。

例如,这就是结果集的样子:

12345   05:40   
12345   05:50   
12345   06:22   
12345   07:55   
12345   08:33   

一旦完成,我想在第三列中插入一个订单值,表示它从最早到最晚的位置。

所以,你会有这样的事情:

12345   05:40   1 <---First entry
12345   05:50   2
12345   06:22   3
12345   07:55   4
12345   08:33   5 <---Last entry

我如何在SQL语句中执行此操作?我可以选择数据和ORDER BY ID,TIMESTAMP。但是,我似乎无法根据分组插入订单值。 :(

3 个答案:

答案 0 :(得分:3)

试试这个update 而不是 insert

<强> Fiddle demo here

;with cte as(
  select id, yourdate, row_number() over(order by id,yourdate) rn
  from yourTable
)
Update ut Set thirdCol = rn
From yourTable ut join cte on ut.Id = cte.id and ut.yourdate = cte.yourdate

注意:如果您需要根据每个ID更新thirdColumn,请使用row_number() over (partition by id, order by order by id,yourdate)

对您的rownumber进行分区

结果:

|    ID | YOURDATE | THIRDCOL |
|-------|----------|----------|
| 12345 |    05:40 |        1 |
| 12345 |    05:50 |        2 |
| 12345 |    06:22 |        3 |
| 12345 |    07:55 |        4 |
| 12345 |    08:33 |        5 |

答案 1 :(得分:1)

使用派生表和更新。

IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end


CREATE TABLE #TableOne
( 
SomeColumnA int , 
LetterOfAlphabet varchar(12) , 
PositionOrdinal int not null default 0 
)




INSERT INTO #TableOne ( SomeColumnA , LetterOfAlphabet )
select 123 , 'x'
union all select 123  , 'b'
union all select 123  , 'z'
union all select 123  , 't'
union all select 123  , 'c'
union all select 123  , 'd'
union all select 123  , 'e'
union all select 123  , 'a'

Select 'pre' as SpaceTimeContinium , * from #TableOne order by LetterOfAlphabet

Update 
#TableOne
Set PositionOrdinal = derived1.rowid
From 
( select SomeColumnA , LetterOfAlphabet , rowid = row_number() over (order by LetterOfAlphabet asc)  from #TableOne innerT1  ) 
as derived1
join #TableOne t1
    on t1.LetterOfAlphabet = derived1.LetterOfAlphabet and t1.SomeColumnA = derived1.SomeColumnA


Select 'post' as SpaceTimeContinium, * from #TableOne order by LetterOfAlphabet


IF OBJECT_ID('tempdb..#TableOne') IS NOT NULL
begin
        drop table #TableOne
end

答案 2 :(得分:0)

要获得所需的订单而不进行插入和更新,您可以设置聚簇索引以便为您处理。以下示例创建一个群集主键。

为此,您必须删除表中已有的任何聚簇索引,因为每个表只能有一个聚簇索引。

CREATE TABLE dbo.Table_1
(
ID int NOT NULL,
DTStamp datetime NOT NULL
) 


ALTER TABLE dbo.Table_1 ADD CONSTRAINT
PK_Table_1 PRIMARY KEY CLUSTERED 
(
ID,
DTStamp
)

插入一些随机数据进行测试......

    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12346,getdate());
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12346,dateadd(mi,1,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12346,dateadd(mi,2,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12346,dateadd(mi,3,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12346,dateadd(mi,4,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12340,dateadd(mi,5,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12340,dateadd(mi,6,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12340,dateadd(mi,7,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12340,dateadd(mi,8,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,1,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,2,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,3,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,4,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,5,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,6,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,7,getdate()));
    INSERT INTO [dbo].[Table_1]([ID],[DTStamp])VALUES(12344,dateadd(mi,8,getdate()));

现在查询你的表并查看订单......

SELECT  [ID] ,[DTStamp]  FROM [Table_1]

如果您需要在查询中显示订单,可以使用over子句添加行号。

SELECT  [ID] ,[DTStamp],row_number() over (partition by [ID] order by [ID] ,[DTStamp]) as SortOdr FROM [Table_1]