SQL 将索引(订单值)设置为列
Posted
技术标签:
【中文标题】SQL 将索引(订单值)设置为列【英文标题】:SQL Set Index (order value) to column 【发布时间】:2018-02-05 10:45:08 【问题描述】:短篇小说
我的Requests
有“行”表。目前,当我向请求添加新行时,无法对其进行排序,因此我添加了Index
列。这将能够添加新行并按照我的意愿对它们进行排序。
我想做的事
我想编写 MSSQL 脚本,由InvoiceRequestId
将旧行的默认值设置为Index
(0, 1, 2)。目前应该按原样设置(Id
顺序)。
当前表
Id InvoiceRequestId Index
2734 620 0
2735 620 0
2736 621 0
2737 622 0
2738 622 0
2739 622 0
...
我想要达到的目标
Id InvoiceRequestId Index
2734 620 0
2735 620 1
2736 621 0
2737 622 0
2738 622 1
2739 622 2
...
编辑
我明白了,有些人开始只为这些行发布答案。这应该是一般的解决方案,我的错,我之前没有澄清这一点。
解决方案
所以感谢下面的答案和这个主题 SQL Update with row_number() ,我找到了以下解决方案:
With IndexUpdate As
(
SELECT [Index],
ROW_NUMBER() OVER (PARTITION BY InvoiceRequestID ORDER BY ID) -1 as RN
FROM [InvoiceRequestRows]
)
UPDATE IndexUpdate SET [Index]=RN
【问题讨论】:
我已经更新了更新的答案,你也可以检查一下。 【参考方案1】:你可以使用row_number()
函数
select *,
(row_number() over(partition by InvoiceRequestId order by Id)-1)
from table
编辑:为子查询结果集使用CTE
,以便用新创建的索引更新索引
;with cte as
(
select *,
(row_number() over(partition by InvoiceRequestId order by Id)-1) newindex
from table
)
update t set t.[Index] = c.newindex
from cte c
join table t on t.Id = c.Id
【讨论】:
谢谢你的回答,但是我如何在更新方法中使用它,所以我的 [Index] 列会使用这些值? 为什么要使用join?声明,我把我原来的问题作为解决方案似乎也有效。 @Taurib .. 是的,不需要明确的join
但是,join
将保证使用适当的id's
更新您的索引【参考方案2】:
如果您想获得这些结果,您不需要添加列,您可以使用 ROW_NUMBER 函数,例如
DECLARE @table TABLE(Id INT, InvoiceRequestId INT);
INSERT INTO @table
VALUES
(2734, 620),
(2735, 620),
(2736, 621),
(2737, 622),
(2738, 622),
(2739, 622);
SELECT Id,
InvoiceRequestId,
ROW_NUMBER() OVER(PARTITION BY InvoiceRequestId ORDER BY Id) AS [Index]
FROM @table;
会给你:
Id InvoiceRequestId Index
2734 620 1
2735 620 2
2736 621 1
2737 622 1
2738 622 2
2739 622 3
它从 1 而不是 0 开始计数,但结果是相同的。如果需要为 0,可以添加“-1”
如果您仍想添加该列,那么您可以使用相同的函数构建一个临时表并从那里插入
【讨论】:
【参考方案3】:以下查询应该可以工作。 ROW_NUMBER -1 正在完成,因为您正在寻找要从 0 开始盯着的索引。
WITH Requests as (
select * from (values
(2734 , 620 , 0)
,(2735, 620 , 0)
,(2736, 621 , 0)
,(2737 , 622 , 0)
,(2738, 622 , 0)
,(2739, 622 , 0)
) t (Id, InvoiceRequestId , [Index])
)
SELECT Id, InvoiceRequestId,(ROW_NUMBER()
OVER(PARTITION BY InvoiceRequestId
ORDER BY Id, InvoiceRequestId ASC)-1) AS Index
FROM Requests
你会得到如下输出。
Id InvoiceRequestId Index
2734 620 0
2735 620 1
2736 621 0
2737 622 0
2738 622 1
2739 622 2
要更新回来,您可以使用以下查询
UPDATE R
SET R.[Index] = N.[Index]
FROM Requests R
INNER JOIN
(
SELECT Id, InvoiceRequestId,(ROW_NUMBER()
OVER(PARTITION BY InvoiceRequestId
ORDER BY Id, InvoiceRequestId ASC)-1) AS [Index]
FROM Requests
) N
ON N.Id = R.ID AND N.InvoiceRequestId= R.InvoiceRequestId
【讨论】:
【参考方案4】:您可以使用 SQL Server 中的 RANK
函数之一,例如创建一个名为 NewIndex
的新列
链接here
SELECT ID, InvoiceRequestID,
ROW_NUMBER() OVER (PARTITION BY InvoiceRequestID ORDER BY ID) -1 AS NewIndex
FROM SomeTable
要更新Index
列,您可以使用它(虽然我还没有测试过这段代码...)
UPDATE SomeTable
SET [Index] = ROW_NUMBER() OVER (PARTITION BY InvoiceRequestID ORDER BY ID) -1
【讨论】:
感谢您的回复。您的解决方案只是选择,但我如何更新 [Index] 以设置此值? @Taurib 您可以在 UPDATE 语句中使用相同的表达式,我将编辑我的答案 用你的更新脚本我得到Windowed functions can only appear in the SELECT or ORDER BY clauses.
以上是关于SQL 将索引(订单值)设置为列的主要内容,如果未能解决你的问题,请参考以下文章
pandas读取csv数据使用reset_index函数把行索引重置为列数据(level参数设置将原行索引中的指定层转化为列数据设置drop参数则删除转化后的数据列)
pandas读取csv数据使用reset_index函数把行索引重置为列数据(level参数设置将原行索引中的指定层转化为列数据设置drop参数则删除转化后的数据列)
pandas读取csv数据header参数指定作为列索引的行索引列表形成复合(多层)列索引使用reset_index函数把行索引重置为列数据(level参数设置将原行索引中的指定层转化为列数据)