Sous-requête MySQL pour faire référence à un champ dans la requête parente
Je fais construire une requête qui effectue un filtrage sur la cote de données.
Supposons que j'ai un tableau simple appelé ratings
comme le suivant, le stockage de données en ligne à partir d'un outil de notation:
+----------------+----------------+--------+ | titre de la page | timestamp | notation | +----------------+----------------+--------+ | Abc| 20110417092134 | 1 | | Abc| 20110418110831 | 2 | | Def| 20110417092205 | 3 | +----------------+----------------+--------+
J'ai besoin d'extraire des pages avec une fréquence élevée de faibles valeurs dans les 10 dernières cotes, et de limiter cette requête pour les pages qui produit un volume d'au moins 20 cotes de la semaine précédente. C'est le ridiculement longue de la requête, je suis venu avec:
SELECT a1.page_title, COUNT(*) AS rvol, AVG(a1.rating) AS theavg,
(
SELECT COUNT(*) FROM
(
SELECT * FROM ratings a2 WHERE a2.page_title = a1.page_title
AND DATE(timestamp) <= '2011-04-24' ORDER BY timestamp DESC LIMIT 10
)
AS latest WHERE rating >=1 AND rating <=2 ORDER BY timestamp DESC
)
AS lowest FROM ratings a1
WHERE DATE(a1.timestamp) <= "2011-04-24" AND DATE(a1.timestamp) >= "2011-04-17"
GROUP BY a1.page_title HAVING COUNT(*) > 20
le haut niveau de la requête recherche les pages avec plus de 20 notes dans la semaine se terminant le 2011-04-24, la sous-requête est censé récupérer le nombre de cotes avec des valeurs entre [1,2] à partir de la dernière 10 notes de chaque article à partir du haut niveau de la requête.
MySQL se plaint que a1.titre de la page dans la clause where de la subsubquery est un inconnu de la colonne, je suppose que c'est parce que a1 n'est pas défini comme un alias dans la deuxième requête de niveau, mais seulement dans la requête de niveau supérieur, mais je suis aucune idée de comment résoudre ce problème.
(édité)
Je suis l'ajout d'une explication de mon suspect ci-dessus au sujet de la croix-niveau de référencement, une autre requête qui fonctionne tout à fait bien, soulignons ici que a1 n'est pas défini dans la sous-requête, mais c'est dans le parent immédiat:
SELECT a1.page_title, COUNT(*) AS rvol, AVG(a1.rating) AS theavg,
(
SELECT COUNT(*) FROM ratings a2 WHERE DATE(timestamp) <= '2011-04-24'
AND DATE(timestamp) >= '2011-04-17' AND rating >=1
AND rating <=2 AND a2.page_title = a1.page_title
) AS lowest FROM ratings a1
WHERE DATE(a1.timestamp) <= '2011-04-17' AND DATE(a1.aa_timestamp) >= '2011-04-11'
GROUP BY a1.page_title HAVING COUNT(*) > 20
source d'informationauteur radrat
Vous devez vous connecter pour publier un commentaire.
Je pense que vous pourriez envisager d'adhérer à deux dans la ligne de vue, il pourrait faire des choses eaiser.
Si tout ce que vous avez est-ce un simple tableau, je n'ai aucune idée de l'endroit où vous êtes en tirant de tous ces autres noms de table, tels que: a1, a2, cotes. Je me sens comme votre SQL est tout à fait un peu de, ou de votre départ de l'information.
La raison de votre avoir l'erreur que vous faites est parce que dans votre sous-sous-sous-requête ne pas inclure de a1 dans votre "à PARTIR de" déclaration... ainsi que le tableau n'est pas inclus, il ne peut pas être référencé dans votre clause where dans cette sous-requête.
que je n'ai pas de table complet pour tester ça... je PENSE que c'est ce que vous cherchez.. mais il n'a pas été testé, et sachant que mes habitudes de codage, il est très rarement ce que j'type parfait de 100% de la première fois 😉
Votre analyse de l'erreur est correcte:
lowest
est connu dans la sous-requête, a1 n'est pas.Je pense que la logique est à l'intérieur. La suite n'est probablement pas le meilleur, mais l'optimiseur peut-être assez intelligent pour combiner les deux sous-requêtes dans le SELECT extérieure. (Si elle n'est pas, au risque de lisibilité, vous pouvez introduire un autre niveau de la sous-requête.)