ROW_NUMBER()OVER with sub set

时间:2016-05-18 18:20:52

标签: sql sql-server sql-server-2008

我一直在利用从其他线程中收集到的信息以及什么不是,并且已经非常接近,但我在这里缺少一些东西来做我需要做的事情。这是我的代码,就像我现在在SQL查询窗口中一样:

WITH n AS (
    SELECT  sub_idx AS current_id,
    ROW_NUMBER() OVER (PARTITION BY EID ORDER BY alt_sub_idx) AS new_id
    FROM
        GETT_Documents 
        )
        UPDATE GETT_Documents
        SET sub_idx = n.new_id
    FROM n
    WHERE EID = 'AC-1.1.i';

这似乎应该可以工作,但不是将sub_idx列从1编号到11,而是将所有1列放在该列中。

View of relevant rows

有眼睛的人能否首先指出我的方式错误?那么也许可以建议我如何改变它以增加10而不是单个数字,因为我想转向并对alt_sub_idx列执行相同的操作,然后执行此操作到此列,但增量为10。 / p>

此致 肯...

6 个答案:

答案 0 :(得分:1)

你的UPDATE没有相关性,所以它只是每次都从cte中抓取第一行。它必须是这样的:

...
UPDATE d        
SET sub_idx = n.new_id
FROM n
INNER JOIN GETT_Documents d
  ON d.sub_idx=n.sub_idx
WHERE d.EID = 'AC-1.1.i';

答案 1 :(得分:1)

SQL Server支持可更新的CTES,因此您不需要JOIN

WITH toupdate AS (
      SELECT sub_idx AS current_id,
             ROW_NUMBER() OVER (PARTITION BY EID ORDER BY alt_sub_idx) AS new_id
      FROM GETT_Documents 
     )
UPDATE toupdate
    SET sub_idx = new_id
    WHERE EID = 'AC-1.1.i';

您的查询问题是缺少连接条件。它执行cross join,因此没有说明用于更新的行。但是,查询根本不需要join

答案 2 :(得分:0)

删除partition by子句。 Eid可能是独一无二的,这就是为什么你输出的原因。

答案 3 :(得分:0)

两个选项:

  1. 使用比Partition By子句
  2. 中现有列更高级别的属性

    OR

    1. 正如Akshey在上一个回答中所建议的,完全删除分区。

答案 4 :(得分:0)

DECLARE @GETT_DOCUMENTS TABLE
(DID INT, EID VARCHAR(1), SUB_IDX INT, ALT_SUB_IDX INT)
INSERT INTO @GETT_DOCUMENTS
VALUES
(1,'A',0,10),
(2,'A',0,20),
(3,'A',0,30),
(4,'A',0,40),
(5,'A',0,50),
(6,'A',0,60),
(7,'A',0,70),
(8,'A',0,80),
(9,'A',0,90),
(10,'A',0,100),
(11,'A',0,110),
(12,'A',0,120)

;WITH n AS 
    (
    SELECT  DID AS DID,
            sub_idx AS current_id,
            ROW_NUMBER() OVER (PARTITION BY EID ORDER BY alt_sub_idx) AS new_id
    FROM    @GETT_Documents 
    )
    --SELECT * FROM N
    UPDATE  @GETT_Documents
            SET sub_idx = n.new_id
    FROM    @GETT_Documents  G
    JOIN    n ON N.DID = G.DID
    WHERE   EID = 'A';

SELECT * FROM @GETT_Documents 

答案 5 :(得分:0)

P Salmon提供了我采用的这个代码,我在这里发布这个答案的唯一原因是为了显示我将作为最终结果放在存储过程中。这是完美的工作,并按原样枚举sub_idx和alt_sub_idx列。下面是我将使用的实际代码以及与我原始帖子中发布的内容进行比较的结果。

感谢P Salmon以及在此贡献的所有人,我从每个人那里学到了很多东西!

WITH n AS 
(
SELECT  DID AS DID,
        sub_idx AS current_id,
        ROW_NUMBER() OVER (PARTITION BY EID ORDER BY alt_sub_idx) AS new_id
FROM    GETT_Documents 
)
--SELECT * FROM N
UPDATE  GETT_Documents
        SET sub_idx = n.new_id
FROM    GETT_Documents  G
JOIN    n ON N.DID = G.DID
WHERE   EID = 'AC-1.1.i';

WITH n AS     (     选择DID为DID,             alt_sub_idx AS current_id,             ROW_NUMBER()OVER(由sub_idx按EID顺序分区)* 10 AS new_id     来自GETT_Documents     )    --SELECT * FROM N.     更新GETT_Documents             SET alt_sub_idx = n.new_id     来自GETT_Documents G.     JOIN n ON N.DID = G.DID     在哪里EID ='AC-1.1.i';

the output