Comment enregistrer temporairement le résultat de la requête, pour l'utiliser dans un autre?

12

J'ai ce problème, je pense que vous pouvez m'aider.
PS Je ne sais pas comment appeler cela, donc si quelqu'un trouve un titre plus approprié, veuillez le modifier.

Contexte

  • Je fais cette application pour rechercher des lignes de transport en commun.
  • Les lignes de bus sont à 3 chiffres et sont uniques et ne changeront jamais.
  • Il faut pouvoir rechercher des lignes de l'arrêt A à l'arrêt B.
  • L'interface utilisateur réussit déjà à suggérer à l'utilisateur de n'utiliser que des noms d'arrêt valides.
  • La condition est de pouvoir afficher si un itinéraire a une ligne directe, et sinon, afficher une combinaison de 2 lignes et même de 3 lignes.

Exemple:

Je dois aller du point A au point D. Le programme devrait montrer:

  • S'il y a une ligne directe AD.
  • Si ce n'est pas le cas, affichez d'autres combinaisons de 2 lignes, telles que AC, CD.
  • S'il n'y a pas de combos 2 lignes, recherchez les combos 3 lignes: AB, BC, CD.

Bien sûr, l'application doit afficher les numéros de ligne de bus, ainsi que le moment de changer de bus.

Ce que j'ai:

Ma base de données est structurée comme suit (simplifiée, la base de données réelle comprend les lieux et les heures et ainsi de suite):

+-----------+
| bus_stops |
+----+------+
| id | name |
+----+------+

+-------------------------------+
|    lines_stops_relationship   |
+-------------+---------+-------+
|  bus_line   | stop_id | order |
+-------------+---------+-------+

lines_stops_relationshipdécrivez une relation plusieurs-à-plusieurs entre les lignes de bus et les arrêts.

Ordre, signifie l'ordre dans lequel les arrêts apparaissent sur une seule ligne. Pas toutes les lignes vont et viennent, et l'ordre a un sens (le point A avec l'ordre 2 vient après le point B avec l'ordre 1).

Le problème

  • Nous découvrons si une ligne peut traverser l'itinéraire assez facilement. Recherchez simplement une seule ligne qui passe par les deux points dans le bon ordre.
  • Comment puis-je trouver s'il y a un combo 2/3 lignes? Je pensais à rechercher une ligne qui correspond à l'arrêt source, et une pour l'arrêt de destination, et voir si je peux obtenir un arrêt commun entre eux, où l'utilisateur peut changer de bus. Comment puis-je me souvenir de cet arrêt?
  • Le combo de 3 lignes est encore plus délicat, je trouve une ligne pour la source et une ligne pour la destination, et puis quoi? Recherchez une ligne qui a 2 arrêts, je suppose, mais encore une fois, comment puis-je me souvenir des arrêts?

tl; dr

Comment puis-je me souvenir des résultats d'une requête pour pouvoir les réutiliser? J'espère y parvenir en une seule requête (pour chacun, une requête pour les itinéraires à 1 ligne, une requête pour 2 et une requête pour les combos à 3 lignes).

Remarque: cela ne me dérange pas si quelqu'un suggère une approche complètement différente de la mienne, je suis ouvert à toutes les solutions.

Accordera toute assistance avec un cookie et un vote positif. Merci d'avance!

Le fantôme de Madara
la source
@eggyal: Je n'ai aucune distance sur les nœuds. De plus, je suis limité dans les déplacements à l'intérieur du réseau (c'est-à-dire que seules certaines lignes de bus se déplacent du point A au point B). Est-il toujours utile pour moi?
Madara's Ghost
Je suggérerais également d'utiliser une procédure stockée sur une seule requête pour cela - s'il est même possible de le faire avec une seule requête. Là, vous pouvez facilement stocker les résultats / variables et les réutiliser.
1
@Truth Il est probablement préférable de vous donner quelques conseils : mysqltutorial.org/stored-procedures-loop.aspx (boucles), mysqltutorial.org/… (cas) - combiné avec quelque chose comme l'algorithme dijkstra, vous devriez être en mesure de résoudre votre problème. Fondamentalement, c'est comme une fonction php - mais sur mysql
1
Semble déjà être sur Stack Overflow - ce lien a plusieurs solutions bien qu'aucune ne soit dans MySQL pour le moment. (Il y a plusieurs réponses qui ne résument pas facilement et la pourriture des liens n'est probablement pas un problème car si ce site disparaît, celui-ci le fera probablement aussi. De plus, il a beaucoup de votes positifs).
psr

Réponses:

3

Vous ne voudrez peut-être pas apporter cette modification drastique à ce stade, mais ce que vous décrivez est exactement le cas d'utilisation des bases de données graphiques . Les bases de données graphiques sont basées sur la théorie des graphes, c'est ce que vous touchez en essayant de trouver un chemin entre 'X' et 'Y' à travers un graphique dirigé des itinéraires de bus.

Si vous n'en avez pas déjà examiné un, jetez un œil à quelque chose comme Neo4J . Il a une API REST et vous pouvez trouver des clients PHP pour cela.

Vous trouverez un tas de personnes de Stack Overflow qui pourraient vous aider avec la mise en œuvre des choses.

Dan McGrath
la source
1
Je suis actuellement en phase de réflexion, je peux tout changer. Je vérifierai vos liens. De plus, cette question est venue de Stack Overflow , je sais qu'ils peuvent m'aider à l'implémenter :)
Madara's Ghost
1
J'allais suggérer des requêtes récursives, mais il semble que MySQL ne les supporte pas, donc cette réponse pourrait être meilleure.
FrustratedWithFormsDesigner
@FrustratedWithFormsDesigner Il pourrait y avoir une solution MySQL très maladroite qui combinerait SP et une liste de contiguïté, mais je ne pense pas que cela vaille la peine d'y penser.
yannis
@YannisRizos: Ce pourrait être un bon défi de golf de code, peut-être? ;)
FrustratedWithFormsDesigner
1
@FrustratedWithFormsDesigner Nah, c'est un bon défi de golf de code
yannis
0

Disons qu'un utilisateur veut aller de $start_idà $end_id(les deux sont des valeurs stop_id valides). Vous pouvez utiliser ces requêtes pour trouver un itinéraire valide de $start_idà $end_id:

  1. Recherche d'itinéraire direct (ligne unique):

    SELECT *
    FROM bus_stops bs1, bus_stops bs2
    WHERE bs1.stop_id=$start_id AND bs2.stop_id=$end_id AND bs1.bus_line=bs2.bus_line
    
  2. S'il n'y a aucun résultat avec la requête précédente, alors recherchez un itinéraire en utilisant 2 lignes:

    SELECT *
    FROM bus_stops bs1, bus_stops bs2, bus_stops bs3, bus_stops bs4
    WHERE bs1.stop_id=$start_id
        AND bs1.bus_line=bs2.bus_line
    AND bs2.stop_id=bs3.stop_id
        AND bs3.bus_line=bs4.bus_line
    AND bs4.stop_id=$end_id
    

Remplacez-les *par les champs que vous devez vraiment récupérer.

Jocelyn
la source
Bonjour Jocelyn et bienvenue! Veuillez lire attentivement notre page d'aide à l'édition pour savoir comment tirer le meilleur parti de Markdown. J'ai édité votre réponse cette fois, vous pouvez vérifier son historique de révision pour voir les modifications que j'ai apportées.
yannis
Pourquoi choisissez-vous dans la même base de données 4 fois de suite?
Madara's Ghost
Et que se passe-t-il si vous avez besoin d' une ligne de bus supplémentaire ( bus_stops bs5) pour terminer l'itinéraire?
FrustratedWithFormsDesigner