Moyen le plus efficace de faire un mysql conditionnel se joindre à plusieurs tables? (Php cadre Yii)

StackOverflow https://stackoverflow.com/questions/3112775

Question

J'ai cinq tableaux:

  1. tab_template
  2. template_group
  3. groupe
  4. groupe_de_l_utilisateur
  5. utilisateur

de Tab_template sont organisés en groupes avec la table relationnelle template_group. sont organisés en groupes avec la table relationnelle groupe_de_l_utilisateur ses utilisateurs. Groupe de peut être public ou privé (à l'aide d'une colonne tinyint booléenne dans le tableau).

Je veux requête pour tous les tab_templates qui sont soit:

  1. Dans le même groupe que l'utilisateur
  2. Ou dans un groupe public

Voici ma requête en cours:

SELECT * FROM tab_template t
LEFT JOIN template_group
  ON template_group.tab_template_id = t.id
LEFT JOIN group
  ON template_group.tab_template_id = group.id
LEFT JOIN user_group
  ON TRUE

 group.private = 0
OU
(template_group.group_id = user_group.group_id
  ET
 user_group.user_id = 2)
GROUP BY t.id;

Il fonctionne, et ce n'est pas lent SUPER en soi, mais il est hacky la façon dont je me joins à la table groupe_de_l_utilisateur.

Le problème est que je dois joindre à la table de groupe_de_l_utilisateur pour un contrôle conditionnel, mais je ne dois faire que l'enregistrement conditionnel si le groupe n'est pas privé.

Je sais qu'au lieu de la troisième LEFT JOIN avec la condition ON vrai que je pourrais ajouter une autre table à la clause FROM (DE tab_template de t, user_group ug) ... mais je ne peux pas le faire parce que la façon dont la classe ActiveRecord de Yû travaille avec I DcCriteria ne peuvent pas modifier cette partie de la déclaration. Je peux modifier à peu près tout autre partie de la requête, mais pas la clause FROM. Consultez l'API ici: http://www.yiiframework.com/doc/api/CDbCriteria Voilà pourquoi je rejoins la table groupe_de_l_utilisateur la façon dont je suis. Certains experts Yii pourraient être en mesure de me aider à résoudre ce problème, mais je ne suis pas sûr que ma requête sera plus rapide par FROMing les tables au lieu de se joindre à eux en tout cas.

Toute aide serait grandement appréciée! Merci

Était-ce utile?

La solution

Ma recommandation pour des situations comme celles-ci est d'utiliser une UNION:

SELECT t.* 
  FROM TAB_TEMPLATE t
  JOIN TEMPLATE_GROUP tg ON tg.tab_template_id = t.id
  JOIN GROUP g ON g.id = tg.tab_template_id  
              AND g.private = 0
UNION 
SELECT t.* 
  FROM TAB_TEMPLATE t
  JOIN TEMPLATE_GROUP tg ON tg.tab_template_id = t.id
  JOIN GROUP g ON g.id = tg.tab_template_id  
              AND g.private != 0
  JOIN USER_GROUP ug ON ug.group_id = g.id

Chemin plus facile à lire, ce qui le rend plus facile à maintenir.

Autres conseils

Je n'ai pas mySql sur cette machine, donc je ne peux pas tester ceci:

SELECT
    TT.col1,
    TT.col2,
    ...
FROM
    Tab_Templates TT
WHERE
    EXISTS
    (
        SELECT *
        FROM
            Template_Groups TG
        WHERE
            TG.tab_template_id = TT.id AND
            TG.private = 0
    ) OR
    EXISTS
    (
        SELECT *
        FROM
            User_Groups UG
        INNER JOIN Template_Groups TG2 ON
            TG2.tab_template_id = TT.id AND
            TG2.group_id = UG.group_id
        WHERE
            UG.user_id = 2
    )
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top