繁体   English   中英

SQL 查询根据另一列中的最大值更新记录

[英]SQL query to update a record based on the max value in another column

问题

我有这张桌子。 (您也可以在DBFiddle中查看它。)

ID 版本 编号。 笔记
1个 NULL 31
2个 1个 31 可口
3个 2个 31 有点好吃
4个 NULL 32
5个 1个 32
6个 2个 32 好吧
7 3个 32 极好
8个 NULL 33 矛盾的
9 1个 33 总的
10 2个 33 呕吐物

第一列是主键。 第二和第三列是整数。 第 4 列是 VARCHAR。

对于版本为 NULL 的每个唯一项目编号,我想查看版本值最高的记录,将其注释字段的内容复制过来。

这在视觉上更容易理解; 命令运行后,表格应如下所示:

ID 版本 编号。 笔记
1个 NULL 31 有点好吃
2个 1个 31 可口
3个 2个 31 有点好吃
4个 NULL 32 极好
5个 1个 32
6个 2个 32 好吧
7 3个 32 极好
8个 NULL 33 矛盾的
9 1个 33 总的
10 2个 33 呕吐物

变动说明

  • 对于第 31 项,“kinda tasty”被复制过来,因为它在版本号最高的记录中,目标单元格未被占用。
  • 对于第 32 项,“fabulous”出于同样的原因被复制了过来。
  • “puke”未被复制以替换“ambivalent”,因为目标单元格已被占用。

问题

在 SQL 服务器中实现此目的的查询是什么?

我知道我需要一种按Item No.将记录分组的方法,找到版本值最高的那个,取其注释值,并将其复制到版本为 NULL 的记录中,但我无法将其转换为SQL。

尝试这个:

UPDATE t SET notes = (
   SELECT TOP 1 s.notes 
   FROM t s 
   WHERE s.item_no = t.item_no 
   ORDER BY version DESC
) WHERE version IS NULL AND notes IS NULL

检查演示

使用可更新的 CTE:

WITH cte AS (
  SELECT *, FIRST_VALUE(Notes) OVER (PARTITION BY ItemNo ORDER BY Version DESC) newNotes 
  FROM tablename
)
UPDATE cte
SET Notes = newNotes
WHERE Version IS NULL AND Notes IS NULL;

请参阅演示

创建一个 CTE 以确定我们需要更新的值,然后使用更新连接语法将其连接到原始表:

with maxVal as
(
    select row_number() over (partition by [Item No.] order by Version desc) rn
        , notes
        , [Item No.]
    from TestTable
    where Version is not null
)
update TestTable
set Notes = maxVal.Notes
from TestTable
left join maxVal
    on TestTable.[Item No.] = maxVal.[Item No.]
    and maxVal.rn = 1
where TestTable.Version is null
    and TestTable.Notes = ''

您可以尝试这种方法:

-- Preparing a table variable
DECLARE @table1 AS TABLE (
    id  INT IDENTITY(1,1) NOT NULL,
    VersionID INT,
    ItemNo INT,
    Note Varchar(50)
)

insert into 
    @table1 (VersionID,ItemNo,Note)
values 
    (NULL,31,''),
    (1,31,'tasty'),
    (2,31,'kinda tasty'),
    (NULL,32,''),
    (1,32,'meh'),
    (2,32,'alright'),
    (3,32,'fabulous'),
    (NULL,33,'ambivalent'),
    (1,33,'gross'),
    (2,33,'puke');

-- update section 
update up set up.Note = db.Note
from @table1 up
inner join 
(
    select a.ItemNo,a.Note
    from @table1 a
    inner join 
    (
        select itemNo,Max(VersionID) as vs
        from @table1
        where Note <> ''
        group by itemNo
    ) as b on a.ItemNo = b.ItemNo and a.VersionID = b.vs
) as db on db.ItemNo = up.ItemNo and up.Note = ''


-- result
select * from @table1

您可以为每个“ Item No. ”选择最大值,然后用“ Notes ”为NULL的相应值更新原始表。

UPDATE tab 
SET [Notes] = t2.[Notes]
FROM       tab t1 
INNER JOIN (SELECT *, MAX(Version) OVER(PARTITION BY [Item No.]) AS Max_Version
            FROM tab)  t2
        ON t1.[Item No.] = t2.[Item No.]
       AND t2.[Version]  = t2.[Max_Version]
       AND t1.[Notes] IS NULL

此处查看演示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM