将具有特定值的列更新为具有相同 ID 的另一列上具有最大值的值

Update column having certain value to a value with max value on another a column with same id

已在另一个问题中问过这个问题,但标准已更改。

我的Table:

 ID | NumDate  | Number
-------------------
| 1 | 20150101 | 0x
| 1 | 20140101 | 12345678
| 1 | 20130101 | 12345
| 2 | 20150101 | 0x
| 2 | 20130101 | 0x
| 2 | 20091111 | 242424
| 3 | 20150101 | 88888
| 3 | 20141010 | 88888
| 4 | 20150101 | 0x
| 4 | 20141010 | 0x
| 5 | 20141010 | 0101010
| 5 | 20141010 | 0101010
| 5 | 20141010 | 0x

每个“0x”都必须更新为 'Number',其中最大的 'NumDate' 不是“0x”。

如果除“0x”外不存在其他值,则不更新。

需要的结果:

ID  | NumDate   | Number
-------------------
| 1 | 20150101 | 12345678      <-- ID = 1, Updated
| 1 | 20140101 | 12345678
| 1 | 20130101 | 12345
| 2 | 20150101 | 242424        <-- ID = 2, Updated
| 2 | 20130101 | 242424        <-- ID = 2, Updated
| 2 | 20091111 | 242424
| 3 | 20150101 | 88888         <- No change on id = 3, '88888' on both rows
| 3 | 20141010 | 88888         <- No change on id = 3, '88888' on both rows
| 4 | 20150101 | 0x            <- No change, there's no *better* 'Number' 
| 4 | 20141010 | 0x            <- No change, there's no *better* 'Number'
| 5 | 20141010 | 0101010
| 5 | 20141010 | 0101010 
| 5 | 20141010 | 0101010       <-- Updated

试过了(thnx Kaf):

;WITH CTE AS (
    SELECT ID, Number, Max(NumDate) NumDate
    FROM TEST_03
    WHERE Number <> '0X'
    GROUP BY ID
)
UPDATE ut SET Number = c.Number
FROM TEST_03 ut
    JOIN CTE c ON ut.ID = c.ID
WHERE ut.Number = '0X'
    JOIN CTE c ON ut.ID = c.ID
WHERE ut.Number = '0x'

我得到:

Column 'TEST_03.Number' is invalid in the select list because it is not 
contained in either an aggregate function or the GROUP BY clause.

我确实看到了聚合函数使用中的错误。不适合这里?

现在,我不知道该如何处理。 也许我应该将 'ID'、'Numdate' 和 'Number' 复制到另一个 table 并使用 JOIN 更新,以保持简单?举个例子,有人吗?

或者也许有一种方法可以在现有的 table 中实现它?

如有任何帮助,我们将不胜感激, 提前致谢!

尝试在您的 CTE 中按编号添加组并删除最后一个加入 see the demo

;WITH CTE AS (
SELECT ID, Number, Max(NumDate) NumDate
FROM TEST_03
WHERE Number <> '0X'
GROUP BY ID, Number
)
UPDATE ut SET Number = c.Number
FROM TEST_03 ut
    JOIN CTE c ON ut.ID = c.ID
WHERE ut.Number = '0X'

我认为最好的解决方案是使用 CROSS APPLY:

;WITH CTE AS (
    SELECT t1.Number, t2.Number as NewNumber
    FROM TEST_03 t1
    CROSS APPLY
    (
       SELECT top 1 Number 
       FROM TEST_03
       WHERE
         t1.ID = ID
         and Number <> '0X'
       ORDER BY NumDate DESC
    ) t2
    WHERE t1.Number = '0X'
)
UPDATE CTE
SET Number = NewNumber

像这样的东西应该可以工作:

update t3
set Number = t1.Number
from dbo.test t3 join dbo.test t1 on t3.id = t1.id
join
(
select id, max(numDate) as maxdate
from dbo.test
where number<>'0x'
group by id
) t2
on t1.id = t2.id and t1.NumDate = t2.maxdate
where t3.number = '0x'