将具有特定值的列更新为具有相同 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'
已在另一个问题中问过这个问题,但标准已更改。
我的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'