2010-05-20 10 views
4

Je suis donc en train d'écrire une requête assez complexe avec une demi-douzaine de jointures, une sous-requête dépendante pour [plus-n-par-groupe], groupement, etc. C'est syntaxiquement valide, mais j'ai clairement fait au moins erreur car elle ne renvoie rien. Dans le passé, j'ai débogué des requêtes valides qui ne retournent rien en supprimant les jointures, en exécutant des sous-requêtes, en supprimant les conditions WHERE et en supprimant le groupement pour voir ce que j'obtiendrais mais jusqu'à présent celui-ci m'a bloqué. Y a-t-il de meilleurs outils ou techniques à utiliser pour ce genre de chose?comment déboguer une requête qui a une syntaxe valide, s'exécute, mais ne renvoie aucun résultat?

Cette requête particulière est pour MySQL si elle compte pour tous les outils spécifiques à la plate-forme.

Modifier: espérait conseils de requête agnostique, mais étant donné que vous devez avoir une requête afin d'exécuter EXPLIQUER, et vous avez besoin EXPLAIN pour en savoir plus sur ce que cela signifie, je suppose que je vais devoir faire du bénévolat la requête Je travaille actuellement sur;)

SELECT 
    artist.entry_id AS artist_id, 
    GROUP_CONCAT(tracks.title ORDER BY tracks.entry_date DESC SEPARATOR ',') AS recent_songs 
FROM 
    exp_favorites AS fav JOIN 
    exp_weblog_titles AS artist ON fav.entry_id = artist.entry_id JOIN 
    exp_weblog_titles AS tracks ON tracks.entry_id = 
     (
      SELECT 
       t.entry_id 
      FROM 
       exp_weblog_titles AS t JOIN 
       exp_relationships AS r1 ON r1.rel_parent_id = t.entry_id 
      WHERE 
       t.weblog_id = 3 AND 
       t.entry_date < UNIX_TIMESTAMP() AND 
       t.status = 'open' AND 
       r1.rel_child_id = artist.entry_id -- this line relates the subquery to the outside world 
      ORDER BY 
       t.entry_date DESC 
      LIMIT 3 -- I want 3 tracks per artist 
     ) 
WHERE 
    artist.weblog_id = 14 AND 
    fav.member_id = 1 
GROUP BY 
    artist.entry_id 
LIMIT 5 

entraînant cette sortie EXPLIQUEZ:

id select_type   table  type possible_keys      key    key_len  ref     rows Extra 
1 PRIMARY    fav   ALL                       293485 Using where; Using temporary; Using filesort 
1 PRIMARY    artist  eq_ref PRIMARY,weblog_id     PRIMARY   4   db.fav.entry_id  1  Using where 
1 PRIMARY    tracks  eq_ref PRIMARY        PRIMARY   4   func    1  Using where 
2 DEPENDENT SUBQUERY r1   ref  rel_parent_id,rel_child_id   rel_child_id 4   db.artist.entry_id 5  Using where; Using temporary; Using filesort 
2 DEPENDENT SUBQUERY t   eq_ref PRIMARY,weblog_id,status,entry_date PRIMARY   4   db.r1.rel_parent_id 1  Using where 

Je parés la requête vers le bas pour l'essentiel à cette question ... fondamentalement tout ce que je en avoir besoin faire est de retourner 3 pistes par art ist.

+2

Pas vraiment une réponse, mais en utilisant EXPLAIN pourrait vous donner des indices. – Guillaume

+0

ouais j'ai regardé la sortie EXPLAIN mais, sauf pour les bases, je ne suis pas vraiment sûr de ce qu'il essaie de me dire. –

+0

Si vous êtes content de partager la sortie d'EXPLAIN, pourquoi ne pas l'ajouter à votre question? :) – Mathew

Répondre

0

Ce que vous avez décrit comme étant votre processus, c'est comment je m'y prendrais. Il n'y a pas de substitut que je connaisse.

Pour votre requête particulière, je suppose que cela a à voir avec la jointure à exp_weblog_titles qui ne semble pas être connecté à l'une des autres tables de la requête.

+0

'exp_weblog_titles AS artist' est ce que je veux finalement filtrer la sous-requête' exp_weblog_titles AS t' pour que je puisse obtenir 3 t par artiste. pas vraiment sûr de ce que vous voulez dire par ces tables ne sont pas connectés –

1

La sous-requête avec LIMIT 3 me semble très suspecte.

Je ne suis pas un expert des normes SQL, mais je suis tenté de dire que c'est la raison de l'erreur. Même si MySQL semble vous permettre de comparer 1 colonne (valeur) à un ensemble de plusieurs lignes (vous voulez en obtenir 3) - je n'essaierais pas de le faire à moins que je n'aie pas le choix.

Je ne crois pas que:

A join B on b.column = (select some-multi-records-sub-query) 

fera la bonne chose et exécutée sous-jointures nécessaires (et cela exigera essentiellement juste une autre jointure, entre B et sous-requête).

Je pense qu'à la place, MySQL essaie de comparer la valeur à l'ensemble de lignes à 3 lignes qui est toujours faux, et c'est la raison pour laquelle vous n'obtenez aucune ligne.

Vous pouvez essayer quelque chose comme ça (pas sûr qu'il fonctionnera tout de suite, vous devrez déboguer, mais je pense que l'idée est claire):

exp_weblog_titles AS artist ON fav.entry_id = artist.entry_id JOIN 
exp_relationships AS r1 ON r1.rel_child_id = artist.entry_id join 
    (
     SELECT 
      t.entry_id as entry_id 
     FROM 
      exp_weblog_titles AS t 
     WHERE 
      r1.rel_parent_id = t.entry_id 
      t.weblog_id = 3 AND 
      t.entry_date < UNIX_TIMESTAMP() AND 
      t.status = 'open' 
     ORDER BY 
      t.entry_date DESC 
     LIMIT 3 -- I want 3 tracks per artist 
    ) as t2 
exp_weblog_titles AS tracks ON tracks.entry_id = t2.entry_id 
Questions connexes