2010-07-29 6 views
1

primaire, j'ai une table qui est est triée 1er par Rappel Date de puis IDForward Retour enregistrements dans MySQL avec les mêmes données dans le

Table On dirait:

ID | remind_date 
1  2011-01-23 
2  2010-02-21 
4  2011-04-04 
5  2011-04-04 
6  2009-05-04 

J'utilise un front PHP fin d'aller de l'avant et revenir les dossiers. Je veux avoir des boutons avant et arrière, mais je rencontre un problème avec les 2 dates de rappel qui sont les mêmes.

Juste pour noter les numéros d'identification ne sont pas en ordre, ils sont ici, mais dans la base de données réelle, ils sont mélangés lors du tri par reminder_date

L'instruction select j'utilise est: (iid $ est l'enregistrement en cours i suis sur)

SELECT id FROM myDB.reminders where remind_date > (SELECT remind_date FROM myDB.reminders where id=$iid) order by remind_date ASC LIMIT 1 

Alors, que se passe quand je reçois les dates qui sont les mêmes ses skips plus d'un parce que sa demande de remind_date>.

Si j'utilise remind_date> =, il renvoie l'enregistrement en cours. Ma solution était alors d'utiliser la limite 2 et de vérifier via PHP si le 1er enregistrement = mon identifiant actuel, s'il utilisait le suivant. mais il y a 3 dates identiques ou 4 etc.

J'ai aussi pensé à utiliser le champ ID mais comme ils sont hors service je ne peux pas ajouter un ID> $ iid.

Des idées? ça marche super sauf 2 dates qui sont les mêmes.

Répondre

1

Vous pourriez être en mesure d'utiliser ceci:

SELECT ID, remind_date 
FROM 
(
    SELECT @prev_id := -1 
) AS vars 
STRAIGHT_JOIN 
(
    SELECT 
     ID, 
     remind_date, 
     @prev_id AS prev_id, 
     @prev_id := id 
    FROM myDB.reminders 
    ORDER BY remind_date, ID 
) T1 
WHERE prev_id = $iid 

Voici un test de ce qui précède avec vos données de test de votre commentaire:

CREATE TABLE Table1 (ID INT NOT NULL, remind_date DATE NOT NULL); 
INSERT INTO Table1 (ID, remind_date) VALUES 
(45, '2011-01-14'), 
(23, '2011-01-22'), 
(48, '2011-01-23'), 
(25, '2011-01-23'), 
(63, '2011-02-19'); 

SELECT ID, remind_date 
FROM 
(
    SELECT @prev_id := -1 
) AS vars 
STRAIGHT_JOIN 
(
    SELECT 
     ID, 
     remind_date, 
     @prev_id AS prev_id, 
     @prev_id := id 
    FROM table1 
    ORDER BY remind_date, ID 
) T1 
WHERE prev_id = 25 

Résultat:

 
ID remind_date 
48 2011-01-23 
+0

J'ai un ensemble de données comme ceci: [45 | 2011-01-14] [23 | 2011-01-22] [48 | 2011-01-23] [25 | 2011-01-23] [63 | 2011-02-19] Il va 45,23,25 .. saute plus de 48. D'autres idées ?? – Phil

+0

@Phil: Je l'ai testé sur les données de test que vous avez fournies dans votre commentaire avec $ iid = 25 et ça marche bien, en retournant l'enregistrement avec id = 48. Essayez d'exécuter le code de test fourni dans ma réponse mise à jour. Vous pouvez l'exécuter dans MySQL Query Browser pour voir que cela fonctionne pour vous-même. Je pense que votre problème doit se trouver ailleurs dans votre code. –

+0

Mark, Vous avez raison! ça marche. Merci beaucoup! tu as sauvé beaucoup de cheveux qui resteront maintenant sur ma tête;) – Phil

0

ajouter une condition O WH ID <> MY_LAST_ID. Cela ne peut pas fonctionner avec des dates identiques et triples, donc vous pouvez collecter des identifiants déjà pris dans un tableau comme (4,5,6) - voir array_push(), imploser avec "," pour convertir en une chaîne (appelons-y YOUR_IDS_STRING) et ajoutez à votre requête:

WHERE id NOT IN(YOUR_IDS_STRING) 

et après chaque make check requête, ne la date a changé et si elle le fait - vous pouvez décharger votre tableau et commencer à partir begining (ce n'est pas neccesary, mais vous donne plus de performance , parce que YOUR_ID_STRING sera seulement aussi long que nécessaire).

Si votre page est rafraîchissante entre les requêtes, essayez peut-être d'appuyer sur YOUR_ID_STRING dans la variable de session, _GET ou les cookies, et de simplement concaténer les identifiants suivants par l'opérateur.=

0

J'ai utilisé le code fourni par Mark Byers et avec de petits changements je l'ai adapté pour naviguer dans des directions opposées (et passer UMNS aussi, non seulement la date et l'ID):

$results = $mysqli->query("SELECT * FROM (SELECT @prev_id := -1) AS vars STRAIGHT_JOIN (SELECT *, @prev_id AS prev_id, @prev_id := ID FROM my_table ORDER BY data, ID) T1 WHERE prev_id = ".$ID);

$results = $mysqli->query("SELECT * FROM (SELECT @next_id := 1) AS vars STRAIGHT_JOIN (SELECT *, @next_id AS next_id, @next_id := ID FROM my_table ORDER BY data DESC, ID DESC) T1 WHERE next_id = ".$ID);

Je l'ai testé sur les dates en double et il navigue auge bien une liste d'enregistrements affichés avec:

$results = $mysqli->query("SELECT * FROM my_table ORDER BY data DESC, ID DESC");