如果我理解你的話,你需要一種方法來正確管理position
列中的值序列,當你插入新的問題時,改變現有的位置一個或刪除問題。
比方說,你有以下的問題表的DDL:
CREATE TABLE `questions` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`question` VARCHAR(256) DEFAULT NULL,
`position` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
和初使數據集這樣
+----+------------+----------+
| id | question | position |
+----+------------+----------+
| 1 | Question 1 | 1 |
| 2 | Question 2 | 2 |
| 3 | Question 3 | 3 |
+----+------------+----------+
若要下令你做明顯的問題清單
SELECT *
FROM questions
ORDER BY position;
To in塞爾特人的問題列表你做的最後一個新問題
INSERT INTO questions (question, position)
SELECT 'New Question', COALESCE(MAX(position), 0) + 1
FROM questions;
結果將是:
+----+--------------+----------+
| id | question | position |
+----+--------------+----------+
| 1 | Question 1 | 1 |
| 2 | Question 2 | 2 |
| 3 | Question 3 | 3 |
| 4 | New Question | 4 |
+----+--------------+----------+
要插入一個新的問題到特定位置(假設到位置3)在列表中,您有兩個查詢做到這一點:
UPDATE questions
SET position = position + 1
WHERE position >= 3;
INSERT INTO questions (question, position)
VALUES ('Another Question', 3);
現在你有
+----+------------------+----------+
| id | question | position |
+----+------------------+----------+
| 1 | Question 1 | 1 |
| 2 | Question 2 | 2 |
| 5 | Another Question | 3 |
| 3 | Question 3 | 4 |
| 4 | New Question | 5 |
+----+------------------+----------+
要交換兩個問題的位置(例如,與IDS 2個問題和5)你做
UPDATE questions AS q1 INNER JOIN
questions AS q2 ON q1.id = 2 AND q2.id = 5
SET q1.position = q2.position,
q2.position = q1.position
讓我們看看我們有什麼
+----+------------------+----------+
| id | question | position |
+----+------------------+----------+
| 1 | Question 1 | 1 |
| 5 | Another Question | 2 |
| 2 | Question 2 | 3 |
| 3 | Question 3 | 4 |
| 4 | New Question | 5 |
+----+------------------+----------+
這就是你做什麼,當用戶點擊您的向上和向下按鈕,提供正確的問題編號。
現在,如果您希望在刪除問題時保持自己的位置順序沒有間隙,那麼可以這樣做。
要從列表的末尾刪除您使用列表的簡單刪除
DELETE FROM questions WHERE id=4;
結果
+----+------------------+----------+
| id | question | position |
+----+------------------+----------+
| 1 | Question 1 | 1 |
| 5 | Another Question | 2 |
| 2 | Question 2 | 3 |
| 3 | Question 3 | 4 |
+----+------------------+----------+
刪除問題在中間(或開始)需要更多的工作。比方說,我們要刪除ID爲這個問題= 5
-- Get the current position of question with id=5
SELECT position FROM questions WHERE id=5;
-- Position is 2
-- Now delete the question
DELETE FROM questions WHERE id=5;
-- And update position values
UPDATE questions
SET position = position - 1
WHERE position > 2;
最後我們
+----+--------------+----------+
| id | question | position |
+----+--------------+----------+
| 1 | Question 1 | 1 |
| 2 | Question 2 | 2 |
| 3 | Question 3 | 3 |
+----+--------------+----------+
UPDATE:爲了使我們的生活更輕鬆,我們可以把它包裝所有在存儲過程中
DELIMITER $$
CREATE PROCEDURE add_question (q VARCHAR(256), p INT)
BEGIN
IF p IS NULL OR p = 0 THEN
INSERT INTO questions (question, position)
SELECT q, COALESCE(MAX(position), 0) + 1
FROM questions;
ELSE
UPDATE questions
SET position = position + 1
WHERE position >= p;
INSERT INTO questions (question, position)
VALUES (q, p);
END IF;
END$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE swap_questions (q1 INT, q2 INT)
BEGIN
UPDATE questions AS qs1 INNER JOIN
questions AS qs2 ON qs1.id = q1 AND qs2.id = q2
SET qs1.position = qs2.position,
qs2.position = qs1.position;
END$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE delete_question (q INT)
BEGIN
SELECT position INTO @cur_pos FROM questions WHERE id=q;
SELECT MAX(position) INTO @max FROM questions;
DELETE FROM questions WHERE id=q;
IF @cur_pos <> @max THEN
UPDATE questions
SET position = position - 1
WHERE position > @cur_pos;
END IF;
END$$
DELIMITER ;
並且像這樣使用它們:
-- Add a question to the end of the list
CALL add_question('How are you today?', 0);
CALL add_question('How are you today?', NULL);
-- Add a question at a specific position
CALL add_question('How do you do today?', 3);
-- Swap questions' positions
CALL swap_questions(1, 7);
-- Delete a question
CALL delete_question(2);
'ORDER BY order_field,some_other_field'?您不必僅按一個字段進行排序...... – 2013-02-17 23:34:19
難道您不能在內存中構建問題ID的圖形,然後在需要時從數據庫中檢索它們嗎? 「有時候我們需要插入新的問題,而且我們需要向上或向下移動問題」建議流程邏輯可以適用於圖表結構 – 2013-02-18 03:05:42