这是content
表:
ContentID | CategoryID | Position | Other1 | Other2
===================================================
1 | 1 | NULL | abcd | efgh
2 | 1 | NULL | abcd | efgh
3 | 1 | NULL | abcd | efgh
4 | 2 | NULL | abcd | efgh
5 | 2 | NULL | abcd | efgh
6 | 2 | NULL | abcd | efgh
这些是我将要运行的查询:
SELECT ContentID FROM content WHERE CategoryID = 1 ORDER BY Position
SELECT ContentID FROM content WHERE CategoryID = 2 ORDER BY Position
现在我想实现向上移动,向下移动,移至顶部并移至底部函数以获取内容。我需要做的就是用数字填充Position列:
ContentID | CategoryID | Position
=================================
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 2 | 1
5 | 2 | 2
6 | 2 | 3
是否可以通过MySQL中的单个查询实现此目的?类似的东西:
UPDATE content
SET Position = <ROW_NUMBER>
WHERE CategoryID = 1
ORDER BY Position
UPDATE content
SET Position = <ROW_NUMBER>
WHERE CategoryID = 2
ORDER BY Position
答案 0 :(得分:11)
这应该有效
update
content,
(
select
@row_number:=ifnull(@row_number, 0)+1 as new_position,
ContentID
from content
where CategoryID=1
order by position
) as table_position
set position=table_position.new_position
where table_position.ContentID=content.ContentID;
但我更愿意先应用它,取消设置用户定义的变量
set @row_number:=0;
你可以在这样的一个声明中做到这一点
update
content,
(
select
@row_number:=ifnull(@row_number, 0)+1 as new_position,
ContentID
from content
where CategoryID=1
order by position
) as table_position,
(
select @row_number:=0
) as rowNumberInit
set position=table_position.new_position
where table_position.ContentID=content.ContentID;
答案 1 :(得分:2)
这是适用于我的解决方案(希望它可以帮助某人):
-- The following query re-populates the "Position" column with sequential numbers so that:
-- a) sequence is reset to 1 for each "group"
-- b) sequence is based on row number relative to each group depending on how ORDER BY is specified
-- c) sequence does not disturb the original order but
-- c.a) fixes NULLs so that they are moved to top
-- c.b) fixes duplicate position values depending on how ORDER BY is specified
-- ContentID is the primary key
-- CategoryID is a foreign key
-- Position column contains relative position of a record
SET @current_group = NULL;
SET @current_count = NULL;
UPDATE
content
SET Position = CASE
WHEN @current_group = CategoryID THEN @current_count := @current_count + 1
WHEN @current_group := CategoryID THEN @current_count := 1
END
ORDER BY CategoryID, Position -- <Column 3>, <Column 4>, ...
答案 2 :(得分:1)
我认为当您对表执行某些操作时,始终运行其他查询会非常繁琐。每当你想在表格中插入/更新某些东西时,我会create trigger。
在您的情况下,建议使用BEFORE UPDATE
和BEFORE INSERT
触发器。如果您还想在删除etntry后保持清洁,请添加AFTER DELETE
触发器。
答案 3 :(得分:0)
初始:
UPDATE content as uc
SET Position = (
SELECT count(*)
FROM content as sc
WHERE sc.CategoryId = uc.CategoryId AND sc.Position is not null)
WHERE uc.Position is null
ORDER BY uc.ContentId
插入之前:
UPDATE content
SET Position = Position+1
WHERE Position >= newPos AND CategoryId = newCat