2011-01-08 41 views
11

這是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 

現在我想實現向上移動,向下移動,移動到頂部並移動到內容的底部功能。我需要做的就是用數字填充位置列:

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

你很可能使用CASE語句,不知何故,但兩個查詢可能會更好。 – dqhendricks 2011-01-08 06:30:18

+0

@Everyone:我只是設法做到了。 – 2011-01-08 12:19:20

+0

`更新內容設置位置= ID` – 2011-01-08 12:42:06

回答

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; 

添加人MCHL未設置用戶:

你可以做,在一個這樣的說法

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; 
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 
0

我認爲這將是非常乏味的,當你做一些操作,以運行其他查詢,所有的時間在桌子上。我會create a trigger每次你想插入/更新表中的東西時觸發。

在你的情況下,BEFORE UPDATEBEFORE INSERT觸發器將是明智的。如果您還想在刪除etntry後保持清潔,請添加AFTER DELETE觸發器。

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>, ... 
相關問題