Effizienteste Weg, eine bedingte mysql verbindet auf mehreren Tabellen zu tun? (Yii PHP-Framework)

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

Frage

Ich habe fünf Tabellen:

  1. tab_template
  2. template_group
  3. Gruppe
  4. user_group
  5. Benutzer

sind Tab_template die in Gruppen organisiert, mit der template_group relationalen Tabelle. Benutzer des mit der user_group relationalen Tabelle in Gruppen organisiert. Gruppe kann öffentlich oder privat sein (eine Tinyint boolean Spalte in der Tabelle verwendet wird).

Ich möchte Abfrage für alle die tab_templates, die entweder:

  1. In der gleichen Gruppe wie der Benutzer
  2. oder in einer öffentlichen Gruppe

Hier ist meine aktuelle Abfrage:

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
WO
 group.private = 0
OR
(template_group.group_id = user_group.group_id
  UND
 user_group.user_id = 2)
GROUP BY t.id;

Es funktioniert, und es ist nicht super langsam per se, aber es ist Hacky die Art, wie ich in dem user_group Tisch kommen.

Das Problem ist, dass ich die user_group Tabelle für einen bedingten Scheck JOIN, aber ich brauchte nur den bedingten Scheck zu tun, wenn die Gruppe nicht privat ist.

Ich weiß, dass anstelle des dritten LEFT JOIN mit der TRUE Zustand ON ich eine andere Tabelle der FROM-Klausel (FROM tab_template t, user_group ug) hinzufügen könnte ... aber ich kann das nicht tun, weil die Art und Weise Yü der Klasse Active Arbeiten mit dem DcCriteria kann ich nicht, dass ein Teil der Aussage ändern. Ich kann fast jeden anderen Teil der Abfrage bearbeiten, aber nicht die FROM-Klausel. Schauen Sie sich die API hier: http://www.yiiframework.com/doc/api/CDbCriteria ist also, warum ich die Art und Weise der user_group Tisch bin Joining ich bin. Einige Yü Experten könnten in der Lage sein, mir zu helfen, dieses Problem zu lösen, aber ich bin nicht sicher, ob meine Abfrage wird schneller durch froming der Tabellen statt dem Joining sie trotzdem.

Jede Hilfe wäre sehr dankbar! Dank

War es hilfreich?

Lösung

Meine Empfehlung für Situationen wie diese ist eine UNION zu verwenden:

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

Weg leichter zu lesen, das macht es leichter zu pflegen.

Andere Tipps

Ich habe mySql nicht auf dieser Maschine, so kann ich diese nicht testen:

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
    )
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top