J'ai une situation MySQL impliquant de nombreuses tables et une jointure à gauche et j'ai du mal à m'en sortir!Résolution du problème de jointure à gauche avec plusieurs tables
Je vais essayer de le simplifier étape par étape.
La tâche principale que j'essaie de faire est de joindre deux tables. La première table contient des éléments et la seconde contient des actions effectuées sur des éléments. J'ai besoin chaque ligne de la table des éléments à sortir (même si aucune action n'a été effectuée sur eux) si une jointure gauche semble être la solution:
select item.ID, count(action.ID) as cnt
from item
left join action on action.itemID=item.ID
group by ID
La prochaine étape est que je dois réellement compter que certain type des articles. Comme je n'ai pas besoin des autres types, je les filtre avec une clause where.
select item.ID, count(action.ID) as cnt
from item
left join action on action.itemID=item.ID
where item.type=3
group by ID
Maintenant, les choses deviennent un peu plus compliquées. J'ai également besoin de filtrer certains éléments en utilisant une autre table (info). Là, je n'étais pas sûr de savoir comment faire ça. Mais une simple jointure et où clause l'a fait.
select item.ID, count(action.ID) as cnt
from (item, info)
left join action on action.itemID=item.ID
where item.type=3 and info.itemID=itemID and info.fr is not null
group by ID
Jusqu'ici tout va bien. Ma requête fonctionne et la performance est comme prévu. Maintenant, la dernière chose que je dois faire est de filtrer certaines actions (ne pas les compter) basées sur une autre table (sous-action). C'est là que les choses deviennent vraiment lentes et me déroutent. J'ai essayé ceci:
select item.ID, count(action.ID) as cnt
from (item, info)
left join (
action join subaction on subaction.actionID=action.ID and subaction.type=6
) on action.itemID=item.ID
where item.type=3 and info.itemID=itemID and info.fr is not null
group by ID
À ce stade, la requête ralentit soudainement de plus de 1000 fois. Je fais évidemment quelque chose de mal!
J'ai essayé une simple requête qui fait presque ce dont j'ai besoin. Le seul problème est que cela ne comprend pas les éléments qui doivent correspondre à des actions. Mais j'ai besoin d'eux aussi.
select item.ID, count(action.ID) as cnt
from item, info, action, subaction
where item.type=3 and info.itemID=itemID and info.fr is not null and
action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6
group by ID
Quelqu'un a une suggestion sur la façon de résoudre un tel problème? Existe-t-il un moyen standard de faire cela? Merci beaucoup !
EDIT
En fait, cette dernière requête que je soumettais est presque ce que je dois: il ne comprend pas les sous-requêtes, est vraiment performant, permet une utilisation optimale de mes index, est facile à lire, etc.
select item.ID, count(action.ID) as cnt
from item, info, action, subaction
where item.type=3 and info.itemID=itemID and info.fr is not null and
action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6
group by ID
la seule petite chose qui ne ne comprend pas fonctionne pas est que lorsque le nombre est item.ID (action.ID) est 0.
Je suppose que ma question est vraiment comment dois-je modifier légèrement ci-dessus que ry pour qu'il renvoie également item.IDs lorsque count (action.ID) est 0. D'après ce que je vois, cela ne devrait pas changer les performances et l'utilisation de l'index. Il suffit d'inclure ces éléments supplémentaires avec 0 comme nombre.
Avez-vous essayé 'EXPLAIN'ing la requête? –