sql >> Database teknologi >  >> RDS >> Mysql

Hvordan styrer vi dynamisk rækkefølge efter et felt i en tabel?

Hvis jeg forstår dig rigtigt, har du brug for en måde til korrekt at administrere rækkefølgen af ​​værdier i position kolonne, når du indsætter nye spørgsmål, ændrer placeringen af ​​et eksisterende eller sletter spørgsmål.

Lad os sige, at du har følgende DDL i din spørgsmålstabel:

CREATE TABLE `questions` (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
    `question` VARCHAR(256) DEFAULT NULL,
    `position` INT(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
);
 

og indledende datasæt som dette

+----+------------+----------+ | id | question | position | +----+------------+----------+ | 1 | Question 1 | 1 | | 2 | Question 2 | 2 | | 3 | Question 3 | 3 | +----+------------+----------+

For at få ordnet liste med spørgsmål du gør indlysende

SELECT * 
  FROM questions 
 ORDER BY position;
 

For at indsætte et nyt spørgsmål til slutningen af ​​spørgsmålslisten du gør

INSERT INTO questions (question, position) 
SELECT 'New Question', COALESCE(MAX(position), 0) + 1
  FROM questions;
 

Resultatet bliver:

+----+--------------+----------+ | id | question | position | +----+--------------+----------+ | 1 | Question 1 | 1 | | 2 | Question 2 | 2 | | 3 | Question 3 | 3 | | 4 | New Question | 4 | +----+--------------+----------+

For at indsætte et nyt spørgsmål til en bestemt position (lad os sige til position 3) i listen gør du det med to forespørgsler:

UPDATE questions
   SET position = position + 1
 WHERE position >= 3;

INSERT INTO questions (question, position) 
VALUES ('Another Question', 3);
 

Nu har du

+----+------------------+----------+ | id | question | position | +----+------------------+----------+ | 1 | Question 1 | 1 | | 2 | Question 2 | 2 | | 5 | Another Question | 3 | | 3 | Question 3 | 4 | | 4 | New Question | 5 | +----+------------------+----------+

Sådan skifter du placering af to spørgsmål (f.eks. spørgsmål med id 2 og 5) gør du

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
 

Lad os se, hvad vi har

+----+------------------+----------+ | id | question | position | +----+------------------+----------+ | 1 | Question 1 | 1 | | 5 | Another Question | 2 | | 2 | Question 2 | 3 | | 3 | Question 3 | 4 | | 4 | New Question | 5 | +----+------------------+----------+

Det er præcis, hvad du gør, når brugeren klikker på dine op- og ned-knapper og leverer korrekte spørgsmål-id'er.

Hvis du nu vil beholde din positionsrækkefølge uden huller, når du sletter spørgsmål, kan du gøre det.

For at slette fra slutningen af ​​listen du bruger simpel slet

DELETE FROM questions WHERE id=4;
 

Resultater

+----+------------------+----------+ | id | question | position | +----+------------------+----------+ | 1 | Question 1 | 1 | | 5 | Another Question | 2 | | 2 | Question 2 | 3 | | 3 | Question 3 | 4 | +----+------------------+----------+

Sletning af et spørgsmål i midten (eller begyndelsen) af listen kræver mere arbejde. Lad os sige, at vi vil slette spørgsmålet med 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;
 

Og endelig har vi

+----+--------------+----------+ | id | question | position | +----+--------------+----------+ | 1 | Question 1 | 1 | | 2 | Question 2 | 2 | | 3 | Question 3 | 3 | +----+--------------+----------+

OPDATERING :For at gøre vores liv nemmere kan vi pakke det hele ind i lagrede procedurer

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 ;
 

og brug dem sådan her:

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



  1. Sådan implementeres SQLCipher, når du bruger SQLiteOpenHelper

  2. Algoritme til at vælge de mest populære steder fra databasen

  3. Enhver måde at vælge fra MySQL-tabel, hvor et felt ender med et bestemt tegn/tal?

  4. c9.io - hvordan man finder værtsadressen for at oprette en mysql-forbindelse i node.js-platformen