Je suis tout à fait certain que nous ne pouvons pas utiliser la clause limite pour ce que je veux faire - alors je voulais trouver s'il y a une autre manière que nous pouvons y accomplir.
J'ai une table qui capture quel utilisateur a visité le magasin. Chaque fois qu'un utilisateur visit un magasin, une ligne est insérée dans cette table. P>
Certains champs sont p>
Ce que je veux, c'est - pour un ensemble de magasins donné, trouvez les 5 principaux utilisateurs qui ont visité le magasin max de fois de fois. P>
Je peux faire ceci 1 magasin à un Temps comme:
Cela me donnera les 5 utilisateurs qui ont visité store_id = 60 les temps max p> Ce que je veux faire Fournit une liste de 10 store_ids et pour chaque magasin Fetch les 5 utilisateurs qui ont visité ce magasin Max Times
Des idées sur la manière dont je peux y parvenir. Je peux toujours écrire une boucle et passer 1 magasin à la fois, mais je voulais savoir s'il y a une meilleure façon p> p>
5 Réponses :
Union peut être ce que vous recherchez.
-- fist store (select store_id,user_id,count(1) as visits from shopping where store_id = 60 group by user_id,store_id order by visits desc Limit 5) UNION ALL -- second store (select store_id,user_id,count(1) as visits from shopping where store_id = 61 group by user_id,store_id order by visits desc Limit 5) ...
Le moyen le plus simple serait d'émettre 10 requêtes distinctes, une pour chaque magasin. Si vous utilisez des requêtes paramétrées (par exemple, en utilisant PDO in php ) Ce sera Soyez assez rapide car la requête sera compilée à la fois. P>
Si cela s'avère toujours trop de ressources, une autre solution serait de mettre en cache les résultats dans la table de magasin - c'est-à-dire Ajoutez un champ qui répertorie les 5 principaux utilisateurs pour chaque magasin comme une simple liste séparée par des virgules. Cela signifie que votre base de données ne serait pas normalisée à 100% mais que cela ne devrait pas être un problème. P>
Hmmm c'est une idée intéressante - vous suggérez donc - chaque fois qu'un utilisateur visite un magasin - à ce moment-là, effectuez une chèque et mettez à jour la colonne Top 5 utilisateurs. J'ai pensé à cette approche, mais j'ai ensuite décidé de penser pourquoi stocker de manière permanente des données pouvant être récupérées avec un SQL simple
@Gubloo: Je voulais dire que vous dirigeriez un script (comme un travail cron, ou pour le premier utilisateur qui visite après minuit, disons) qui feraient les mises à jour. Ce que vous avez dit peut toujours être trop intensif en ressources. Vous avez raison, si vous pouvez obtenir les données avec une simple requête, c'est certainement meilleur, mais cela ressemble à votre réponse acceptée est assez loin de SIMPLE;)
:) - Bien que cette requête ait l'air complexe - je ne suis pas sûr de la manière dont la ressource intensive est-elle - mais au moins son moyen simple d'obtenir les résultats à la volée.
Préoccupation majeure sur ici est le nombre de fois où vous interrogez une base de données. Si vous interrogez plusieurs fois de votre script. Son simple gaspillage de ressources et doit être évité. C'est vous ne devez pas exécuter une boucle pour exécuter le SQL plusieurs fois en incrémentant certaines valeur. Dans votre cas 60 à 61 et ainsi de suite.
solution 1:
Créer une vue
Voici la solution p> utilise maintenant p> ceci est limité car vous ne pouvez pas le rendre dynamique.
Et si vous avez besoin de 60 à 100 au lieu de 60 à 66. P> Solution 2:
Procédure d'utilisation.
Je ne vais pas entrer dans la façon d'écrire une procédure cuz sa fin de nuit et je dois dormir. :)
Eh bien, la procédure doit accepter deux valeurs 1er numéro inital (60) et 2e comptage (6)
À l'intérieur de la procédure Créez une table temporaire (curseur) pour stocker des données, puis exécutez une boucle à partir du nombre initial jusqu'à la date de comptage.
Dans votre cas de 60 à 66
À l'intérieur de la boucle Écrire le script souhaité remplaçant 60 avec une variable de boucle. P> et ajoute le résultat dans la table temporaire (curseur). P> espère que cela va résoudre votre problème.
Désolé je ne pouvais pas vous donner le code. Si vous en avez encore besoin, plz m'envoie un message. Je vous le donnerai quand je me lève le lendemain matin. P> p>
Si vous ne sauvegarderez pas les données sur le moment où un utilisateur a visité un magasin ou quelque chose comme ceci, vous pouvez simplement mettre à jour la table chaque fois qu'un utilisateur visite un magasin au lieu d'ajouter une nouvelle ligne. p> Mais je pense que cela ne fonctionnerait pas, car aucun utilisateur_id ni store_id n'est unique. Vous devez ajouter une clé primaire unique comme ceci: magasin d'utilisateurs ou autre chose. P> Un autre avis serait de sauvegarder ces données (combien de fois qu'un utilisateur était dans un magasin) dans une table séparée contenant de l'ID , user_id, store_id, visites et incrémentation des visites chaque fois que vous ajoutez également une nouvelle ligne à votre table existante. p> Pour obtenir le top5, vous pouvez ensuite utiliser: p> SELECT `visits`, `user_id` FROM `user_store_times` WHERE `store_id`=10 ORDER BY `visits` DESC LIMIT 5
Merci pour sur la mise à jour de clé en double visites codecode> visites code> + 1 chose.
Utilisation de deux variantes utilisateur et compter le même store_id consécutif, vous pouvez remplacer La première sous-requête (A) est celle qui groupe et commander les données afin de disposer de données telles que: p> La seconde sous-requête (B) init la variable utilisateur alors nous choisissons toutes les données de la sous-requête ( a) Vérification de la condition dans le cas code>. p> Vérifiez que le précédent Store_ID ( Si le précédent store_id est égal à Nous vérifions que le nombre est dans la valeur que nous voulons, de sorte que le donc avec nos données de test: p> <= 5 code> avec la limite que vous souhaitez @prev code> avec -1 et @Count code> avec 1 p>
@prev code>) que nous avons vu est différent de la page actuelle Store_ID.
Depuis le premier @prev code> est égal à -1, il n'y a rien qui correspond à la correspondance actuelle de STORE_ID afin que la condition <> code> est vraie que nous entrons alors est le second cas qui servit simplement à Modifiez la valeur @prev code> avec le store_id actuel. C'est l'astuce afin que je puisse changer les deux variable utilisateur @count code> et @prev code> dans le même état. P> li>
@prev code> juste incrémenter le @Count code> variable. p> li>
<= 5 code> p> l> l>
ul>
Hey Patrick - Je n'ai jamais vu une question comme ceci :) Mais ça marche parfaitement. J'ai essayé avec mes données de test et donne les résultats exacts que je cherchais. Je devrai maintenant étudier ce que fait cette requête. Merci beaucoup
Hey Patrick - Je n'ai jamais vu une question comme ceci :) S'il vous plaît expliquer le code. Afin que nous puissions en apprendre de cela. Je serai reconnaissant.
@Gubloo, @rahul prasad a ajouté une explication
Merci Merci Patrick - Cette explication était très claire et serviable. Appréciez-le.
MySQL n'a pas de fonctions analytiques - Row_Number, grade, dense_rank - que vous utiliseriez normalement pour résoudre des situations comme celles-ci.