如何使用第二个纬度结果更新最后一条记录[SQLServer]

时间:2019-03-30 14:03:23

标签: sql sql-server sql-server-2005 sql-update

我想用倒数第二行的通过/失败结果更新表的最后一个条目。如果表中只有一行,查询就不会失败。

这是我所拥有的代码,但是ist仅使用第一个条目而不是第二个最后一个条目进行更新。寻求帮助

UPDATE DB.dbo.Testergebnisse 
SET 
    Pass = (
        SELECT TOP 1 Pass
        FROM DB.dbo.Testergebnisse
        WHERE 
            TestergebnisID != ( 
                SELECT MAX(TestergebnisID) FROM DB.dbo.Testergebnisse 
            )
            AND TestaufstellungID = 3166 
        ORDER BY TestergebnisID DESC
    ),
    Fail = (
        SELECT TOP 1 Fail
        FROM DB.dbo.Testergebnisse
        WHERE 
            TestergebnisID != ( 
                SELECT MAX(TestergebnisID)  FROM DB.dbo.Testergebnisse 
            ) 
            AND TestaufstellungID = 3166 
            ORDER BY TestergebnisID DESC
    )
WHERE 
    DB.dbo.Testergebnisse.TestergebnisID = ( 
        SELECT TOP 1 TestergebnisID 
        FROM DB.dbo.Testergebnisse 
        WHERE TestaufstellungID =  3166 
        ORDER BY TestergebnisID DESC
    )

SQL Server版本:9.0.5057

3 个答案:

答案 0 :(得分:5)

我不确定是否正在关注。给定这样的数据:

TestergebnisID TestaufstellungID Pass        Fail
-------------- ----------------- ----------- -----------
1              1                 10          12
2              1                 5           6
3              1                 3           4
4              2                 0           0

您想从TestergebnisID = 2的记录中更新TestergebnisID = 3的行,并带有Pass和Fail,就是这样吗?还是应该用记录1中的数据更新记录2?

对于前者,这应该可以解决问题:

;WITH rec AS
(
    SELECT this.TestaufstellungID 
         -- most recent for the given test run
         , MAX(this.TestergebnisID) AS LastTestergebnisID 
         -- find the previous 
         , PrevTestergebnisID =
           (SELECT MAX(prev.TestergebnisID) 
              FROM Testergebnisse prev 
             WHERE prev.TestaufstellungID = this.TestaufstellungID  
               AND prev.TestergebnisID < MAX(this.TestergebnisID )
           ) 
      FROM Testergebnisse this
     GROUP BY this.TestaufstellungID
)
UPDATE mostRecent
   SET Pass = prev.Pass
     , Fail = prev.Fail
  FROM Testergebnisse mostRecent
  JOIN rec
    ON rec.LastTestergebnisID = mostRecent.TestergebnisID 
  JOIN Testergebnisse prev
    ON prev.TestergebnisID = rec.PrevTestergebnisID 

礼物:

TestergebnisID TestaufstellungID Pass        Fail
-------------- ----------------- ----------- -----------
1              1                 10          12
2              1                 5           6
3              1                 5           6       <-- 1 row affected
4              2                 0           0

如果您希望所有这些文件都使用其前辈的值进行更新,则:

;WITH rec AS
(
    SELECT this.TestaufstellungID 
         -- most recent for the given test run
         , this.TestergebnisID
         -- find the previous 
         , PrevTestergebnisID =
           (SELECT MAX(prev.TestergebnisID) 
              FROM Testergebnisse prev 
             WHERE prev.TestaufstellungID = this.TestaufstellungID  
               AND prev.TestergebnisID < this.TestergebnisID
           ) 
      FROM Testergebnisse this
)
UPDATE mostRecent
   SET Pass = prev.Pass
     , Fail = prev.Fail
  FROM Testergebnisse mostRecent
  JOIN rec
    ON rec.TestergebnisID = mostRecent.TestergebnisID 
  JOIN Testergebnisse prev
    ON prev.TestergebnisID = rec.PrevTestergebnisID 

这将更新第2行(从1开始)和第3行(从2开始):

TestergebnisID TestaufstellungID Pass        Fail
-------------- ----------------- ----------- -----------
1              1                 10          12
2              1                 10          12       <--
3              1                 5           6        <--
4              2                 0           0

答案 1 :(得分:0)

如果我正确地跟随了您,应该可以使用可更新的公用表表达式来简化查询,例如:

WITH cte AS (
    SELECT 
        TestergebnisID, 
        TestaufstellungID,
        Pass, 
        Fail,
        ROW_NUMBER() OVER(PARTITION BY TestaufstellungID ORDER BY TestergebnisID DESC) rn,
        LEAD(Pass)    OVER(PARTITION BY TestaufstellungID ORDER BY TestergebnisID DESC) prev_pass,
        LEAD(Fail)    OVER(PARTITION BY TestaufstellungID ORDER BY TestergebnisID DESC) prev_fail
    FROM DB.dbo.Testergebnisse
    WHERE TestaufstellungID = 3166
)
UPDATE cte 
SET Pass = prev_pass, Fail = prev_fail 
WHERE rn = 1

CTE使用窗口功能执行以下操作:

  • 通过降序ROW_NUMBER()(使用TestergebnisID)对每个记录ROW_NUMBER()进行排名
  • Pass(使用Fail)检索先前记录的TestergebnisIDLEAD()
  • 操作在具有相同TestaufstellungID的记录组内执行(您只需删除CTE中的WHERE子句即可处理所有TestaufstellungID而不是仅其中之一)< / li>

然后,主查询仅选择记录最多的记录(rn = 1),并从上一条记录中的值分配PassFail

答案 2 :(得分:0)

如果分区不可用,则可以将最后两行插入到临时表中。这样,您的最大值是最后一行,而您的最小值是倒数第二行。

这会为您提供要设置的值的ID和要更新的行的ID,以及要使用的值。

<div *ngIf="isInitialized" [ngClass]="['table-widget-container', 'basic-container']">
.
.
.
</div>