Frage

select u.user, g.group, u2g.something     von Benutzern, Gruppen, u2g     wobei users.u = u2g.u und groups.g = u2g.g

, dass gibt Daten wie folgt aus:

user, group, something
----------------------
1   , 3,     a
1   , 5,     b
2   , 3,     c
3   , 3,     d
4   , 5,     e

Jetzt würde Ich mag diese Abfrage so begrenzen, dass es nur Benutzer zeigt, die beide in den Gruppen 3 und 5 - so wäre es nur zurückgeben {1,3, a}, { 1,5, b} für meine Beispieldaten.

bearbeiten. Ich eine andere Spalte zu den Daten hinzugefügt, weil es eine falsche Lösung sein kann durch eine Gruppe mit

edit2: sorry, ich wurde von Dokumentation der Irre geführt. MySQL 4.0 nicht unterstützt Unterabfragen: (

EDIT3: Diese SQL programmatisch für eine beliebige Anzahl von Gruppen generiert werden (na ja, bis zu 20 in der aktuellen Spezifikation), so mag ich Lösungen zu vermeiden, die mir zu viel zusätzliche Codierung zu tun geben. Wenn keine Lösung gefunden wird, werde ich ändern nur die resultierende .Net 1.1 Datatable, aber ich möchte vermeiden, dass, wenn möglich.

Edit4: jede neue Idee? Vielleicht ist einer ohne Unterabfragen, die IN enthalten (3,5)?

War es hilfreich?

Lösung

Doppel beitreten Verwendung mit Gruppen-Tabelle gibt Ihnen das richtige Ergebnis:

  select u.user, u2g.something 
  from   users 
  INNER JOIN u2g ON users.u = u2g.u
  INNER JOIN groups g1 ON u2g.g = g1.g AND g1.group = 3
  INNER JOIN groups g2 ON u2g.g = g2.g AND g2.group = 5
  /* try this for two rows, one for each group */
  INNER JOIN groups ON u2g.g = groups.g

Allerdings bedeutet dies nicht genau Ihre Anfrage entspricht, dass Sie zwei Reihen wollen, eine für jede Gruppe. Dies wird Ihnen nur eine Zeile geben, Sie könnten in der Lage sein, es mit Gruppen erneut zu verbinden dafür Rendering zwei Reihen.

Ein weiteres Beispiel (wenn Sie die Auswahl des gleichen groupID, die Sie Karte gegen):

SELECT u.uID, gm.something 
FROM cdcms_users u 
inner join cdcms_group_memberships gm1 on gm1.uID = u.uID AND gm1.gID = 32
inner join cdcms_group_memberships gm2 on gm2.uID = u.uID AND gm2.gID = 33

Andere Tipps

select u.user, g.group, u2g.something 
from users u, groups g, u2g 
where u.user = u2g.user and g.group = u2g.group 
    where exists 
     (select 1 
         from u2g u2g2 
        where u2g2.user=u.user and u2g2.group in(3,5))

Etwas in diese Richtung?

select u.[user], g.group
from     u
    inner join ug on ug.userid = u.id   
    inner join g on g.id = ug.groupid
    inner join 
    (
        select ug.userid
        from ug
        where ug.groupid in (1,2)
        group by ug.userid
        having count(*) = 2
    ) sub on sub.userid = u.id

-Edoode

Ganz scheußlich nicht-allgemeine Lösung, die in zwei Reihen in Oracle-Ergebnisse:

  select users.u, groups.g
    from   users , groups, u2g, groups g2, u2g u2g2
    where  users.u = u2g.u 
           and users.u = u2g2.u
           and groups.g = u2g.g
           and g2.g = u2g2.g
           and (groups.g in (3,5) and g2.g in (3,5) and groups.g <> g2.g)
           ;

Warum groups wird in der Abfrage verwendet? Es ist nur zugegriffen Feld (g) existiert in u2g. Ich denke, Sie wollen wahrscheinlich auch von dort eine Schiffsladung von Sachen bringen.

Um die Art des Suchresultates Sie ohne die Verwendung von Unterabfragen Sie mit einem echten Chaos am Ende beschreiben kommt man hin: eine quadratische Explosion des Abfragetextes

Sie werden etwas von der folgenden Form müssen:

select users.u, groups.g, u2g0.something
from users u, groups g, u2g u2g0, u2g u2g1
where groups.g = 3
     and users.u = u2g0.u
     and u2g0.g = 3
     and users.u = u2g1.u
     and u2g1.g = 5
union all
select users.u, groups.g, u2g1.something
from users u, groups g, u2g u2g0, u2g u2g1
where groups.g = 5
     and users.u = u2g0.u
     and u2g0.g = 3
     and users.u = u2g1.u
     and u2g1.g = 5

Da dies eine programmatisch generierte Abfrage ist, werde ich eine Web-Seite-Scripting-ähnliche Schreibweise hier verwenden, um die Abfrage Konstruktion zu beschreiben. Ich werde auch den Ausschlag machen und unberechtigte Annahme vereinfacht, dass die Gruppenkennungen sind nicht als möglicher SQL-Injection-Angriff Vektor. : -)

<% for(int i = 0; i < requiredGroups.Length; i++) { %>
  <% if(i > 0) { %>
    union all
  <% } %>
select users.u, groups.g, u2g<%=i%>.something
from users u, groups g
  <% for(int j = 0; j < requiredGroups.Length; j++) { %>
     , u2g u2g<%=j%>
  <% } %>
where groups.g = <%=requiredGroups[i]%>
  <% for(int j = 0; j < requiredGroups.Length; j++) { %>
     and users.u = u2g<%=j%>.u
     and u2g<%=j>.g = <%=requiredGroups[j]%>
  <% } %>
<% } %>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top