我有以下表格:
create table dbo.Files (
Id int identity not null constraint PK_Files_Id primary key (Id),
Content varbinary (max) null,
Name nvarchar (280) null
)
create table dbo.BookFiles (
BookId int not null,
FileId int not null,
constraint PK_BookFiles_Id primary key (BookId, FileId)
)
alter table dbo.BookFiles
add constraint FK_BookFiles_BookId foreign key (BookId) references Books(Id) on delete cascade on update cascade,
constraint FK_BookFiles_FileId foreign key (FileId) references Files(Id) on delete cascade on update cascade;
一些数据如下:
BookId FileId Id Name Content
1 1 1 image
1 2 1 image
2 3 2 image
3 4 3 image
有些书有2张图片(BookdId = 1),有些有1张图片(BookId = 2,3)。
我需要将所有文件的名称重命名为:
我知道如何更新所有行中的值:
UPDATE files SET name = "image1";
但我不知道如何设置“image1”和“image2”如上所述。
有人可以帮助我吗?
使用子查询过滤掉具有多个图像的书籍
update t set t.name = case when fileid = 1 then 'ima1' else 'ima2' end
from table t
where bookid in (
select bookid from table
group by bookid
having count(*) > 1
)
为了更新所有文件图像,您可以使用排名功能row_number()
with cte as
(
select *,
row_number() over (partition by b.BookId order by b.FileId) Seq
from BookFiles b
inner join Files f ON f.Id = b.FileId
)
update cte set name = concat(name, Seq)
从您的问题中获取数据,下面的代码片段可以根据您的需要为您提供结果 -
declare @t table (BookId int, FileId int, Id int, Name nvarchar(280), Content varbinary (max))
insert into @t values
(1, 1, 1, 'image',null),
(1, 2, 1, 'image',null),
(2, 3, 2, 'image',null),
(3, 4, 3, 'image',null)
;with cte as
(
select *, ROW_NUMBER() OVER(PARTITION BY BookId ORDER BY BookId) rn
from @t
)
select BookId,FileId,Id,(Name+cast(rn as nvarchar(1))) AS Name,Content from cte
你可以试试CTE
。它不仅仅适用于具有相同ID的2个图像,它适用于您对书籍的任意数量的图像,该数字将相应地附加。
;WITH CT AS
(
SELECT BOOKID, FILEID, ROW_NUMBER() OVER
(PARTITION BY BookId ORDER BY BOOKID) AS RN , NAME
FROM BookFiles BF INNER JOIN Files F ON F.Id = BF.FileId
)
UPDATE CT
SET NAME= 'image' + CAST(RN AS VARCHAR(10))
注意:您对CTE
所做的更新将级联到源表。