T-Rex: Count mit subselect Abfrage

Moin,

da gibt es 3 Tabellen. Eine Tabelle hat Rezepte (R) eine Tabelle hat Eigenschaften (E) und eine Verbindungstabelle (RE) mit 2 relevanten spalten RE_ID_R (Verbindung zu R) und RE_ID_E (Verbindung zu E). Die Namen habe ich vereinfacht.

Ziel ist die Anzahl an Rezepten zu einer Eigenschaft aus der Datenbank zu holen. Soweit kein Problem. Hat der User jedoch durch das wählen einer Eigenschaft eine Eingrenzung getroffen soll diese mit berücksichtigt werden.
Beispiel:
Eine Eigenschaft (süß) hat 50 Rezepte. Wählt man eine Eigenschaft (desert) hat die Kombination zwischen gewählte Eigenschaft und möglicher Eigenschaft nur noch 20 Rezepte. Also Eigenschaft süß hat 50 Rezepte, desert + süß hat nur noch 20 Rezepte.

Ich bekomme dieses §$%§$"§$ Query einfach nicht hin....

Aber eins nach dem anderen. Als erstes ein Query mit dem ich zähle wie viele Eigenschaft pro Rezept identisch sind:

select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" group by RE_ID_R

Jetzt werden die Rezepte aussortiert deren Anzahl an identischen Eigenschaften nicht der gewünschten Anzahl entspricht:

select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" group by RE_ID_R having ANZAHL = 2

Jetzt bekomme ich so viele Zeilen zurück wie es Rezepte mit den zwei gewünschten Eigenschaften gibt. Die zähle ich alle zusammen:

select count(*) from (select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" group by RE_ID_R having ANZAHL = 2 ) as muss

Jetzt hätte ich tatsächlich die Anzahl an Rezepten mit den gewünschten Eigenschaften. Jetzt würde ich gerne alle Eigenschaften durchgehen und Eigenschaften Abhängig die Anzahl berechnen also:

select E.*, (select count(*) from (select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" or RE_ID_E = E_ID group by RE_ID_R having ANZAHL = 3 ) as muss ) as REZEPTE from E

Ich lade also alles von der Eigenschafttabelle dazu. Im Subquery habe ich die Abfrage um ein Feld erweitert. Das Having habe ich um eine Zahl erhöht. Das Problem - MySQL sagt jetzt, dass das Feld E_ID nicht bekannt ist. E_ID ist dem Subquery anscheinend nicht bekannt. Somit scheitert dieser Ansatz :(.

Hoffe ich habe mich verständlich ausgedrückt. Die MySQL spielt keine Rolle da es ein hoffentlich allgemeines Problem ist.

Gruß
sub
T-Rex

  1. Tach!

    Das Problem - MySQL sagt jetzt, dass das Feld E_ID nicht bekannt ist. E_ID ist dem Subquery anscheinend nicht bekannt.

    Ja, weil E_ID kein Feld der FROM-Klausel-Tabellen der Subquery ist. Das voranstellen des Tabellen-Namen (oder dessen Alias) könnte helfen: E.E_ID

    dedlfix.

    1. Ja, weil E_ID kein Feld der FROM-Klausel-Tabellen der Subquery ist. Das voranstellen des Tabellen-Namen (oder dessen Alias) könnte helfen: E.E_ID

      Nein habe ich schon probiert :(.
      Gibt es eventuell eine Alternative für den Query?
      Danke für deine Antwort

      Gruß
      alter und native
      T-Rex

  2. Jetzt werden die Rezepte aussortiert deren Anzahl an identischen Eigenschaften nicht der gewünschten Anzahl entspricht:

    select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" group by RE_ID_R having ANZAHL = 2

    Da steht in jeder Ergebniszeile eine zwei, die Anzahl der Zeilen entspricht der Anzahl Rezepte die beide Eigenschaften haben. Zeilen für ein Rezept mit anderen Eigenschaften sind hier nicht dabei, du schließt damit also nicht Rezepte aus die mehr als diese beiden Eigenschaften haben.
    Falls ich mich bei meiner Interpretation täusche bitte korrigieren.

    Was verstehst du unter Anzahl an identischen Eigenschaften?

    Jetzt würde ich gerne alle Eigenschaften durchgehen und Eigenschaften Abhängig die Anzahl berechnen

    Erklär mal diesen Satz genauer. Ich habs mir ziemlich lange angesehen aber ich blicke da nicht durch.

    1. Also ich finde, dass was ich machen möchte sehr komplex. Es ist sehr kompliziert es zu erklären. Deshalb habe ich den Query schrittweise aufgebaut, damit ein dritter es leichter hat meine Gedanken zu verfolgen. Ich habe vorher im Internet ein wenig nach einer Lösung gesucht. Da scheißen einige ja einen immens langen Query ins Forum und am Ende kommt ein "Such mal Fehler".

      Bei meinem Beispiel hat der User über eine Webseite (oder wie auch immer) bereits 2 Eigenschaften gewählt - süß (2) und Desert (17). Jetzt möchte ich wissen wie viel Rezepte die restlichen Eigenschaften in Kombination mit den gewählten Eigenschaften haben.

      Also gehe ich die Eigenschaften durch. Dann wird geguckt wie viel Rezepte hat sauer + süß + desert, vegan + süß + desert etc...
      Damit ich keine X Abfragen habe versuche ich das alles in einer Abfrage zu machen.

      Den Query den du jetzt rausgezogen hast war nur ein Schritt zum Ganzen.

      select E.*, (select count(*) from (select count(*) as ANZAHL from RE where RE_ID_E = "2" or RE_ID_E = "17" or RE_ID_E = E_ID group by RE_ID_R having ANZAHL = 3 ) as muss ) as REZEPTE from E

      Das wäre der komplette Query. "2" und "17" sind gewählt, RE_ID_E = E_ID wäre die "dynamische" Eigenschaft (keine Ahnung wie ich das sonst nennen soll).
      Der Query hätte theoretisch die richtige Logik und würde mir die Ergebnisse so liefern wie ich sie brauche, aber wie gesagt der Subquery kennt "E_ID" nicht.

      Also sehe ich aktuell zwei Lösungsansätze. Entweder schaffe ich es irgendwie das "E_ID" bekannt wird oder es gibt einen komplett anderen Ansatz. Bei meinem alten Arbeitgeber habe ich mal etwas mit Rollup gebaut. Soweit ich mich jedoch in das Thema Rollup wieder eingelesen habe, bringt mir Rollup nichts ... oder doch?

      Gruß
      von Russland Sanktioierter
      T-Rex

      1. Ich würde das ganz anders angehen, auch wenns mehr als eine Query wird. Kannst du zum Beispiel temporäre Tabellen nutzen?
        Da würde ich dann alle Rezepte einstellen die überhaupt in Frage kommen. D.h. die alle Eigenschaften haben die sie haben sollen.
        Dann mit der Tabelle dann im zweiten Schritt zählen wie viele Eigenschaften sie insgesamt haben.
        Da hast du dann wenigstens eine Chance das ganze zu verstehen.

        Mich hat schon verwirrt dass du count(*) selektierst, obwohl das nirgends weiterverwendet wird.

      2. Moin,

        Bei meinem Beispiel hat der User über eine Webseite (oder wie auch immer) bereits 2 Eigenschaften gewählt - süß (2) und Desert (17). Jetzt möchte ich wissen wie viel Rezepte die restlichen Eigenschaften in Kombination mit den gewählten Eigenschaften haben.

        du möchtest also wissen, dass es bei diesen Rezepten (süß + sauer) auch noch "5 x vegetarisch" gibt, korrekt?

        Ich habe mal versucht das rein gedanklich nachzuvollziehen. Vermutlich brauchst du ein SQL-Statement wie folgendes:

          
        -- Eigenschaften + Anzahl Rezepte: "grün (3)", "vegetarisch (6)" etc.  
        SELECT t3.e, COUNT(DISTINCT t3.id)  
        FROM re t3  
        WHERE id IN (  
          -- Rezepte (ID) wo süß + sauer  
          SELECT DISTINCT t1.id  
          FROM re t1  
          INNER JOIN re t2 ON t1.id = t2.id  
          WHERE t2.e = <süß> AND t2.e = <sauer>  
        )  
        GROUP BY t3.e  
        
        

        RE ist hier die Rezept/Eigenschaft-Tabelle.

        1. Was ist t2 ?

          Gruß
          einwerfender
          T-Rex

          1. Hab's geschnallt... erst lesen dann schreiben -> bitte löschen falls möglich und kein großer Aufwand.

        2. Also erstmal super vielen Dank für deine Mühe!

          WHERE t2.e = <süß> AND t2.e = <sauer>

          Habs ausprobiert und bin hieran gescheitert.
          t2.e kann nicht süß und sauer sein. Es hat nur einen Wert. Wenn ich OR nehme passt der Query zwar, die Logik hätte sich aber dahingegen geändert das ein Rezept nicht mehr beide Eigenschaften haben muss ("süß" UND "sauer") sondern nur noch eines von beiden.

          Gruß
          zweifelnder
          T-Rex

          1. Moin,

            ja das wäre so falsch aber du könntest dass auch umschreiben

              
            WHERE t1.e = <süß> AND t2.e = <sauer>  
            
            

            Für das Erfassen der Rezepte mit bestimmten Kriterien hattest du aber ja selber schon ein passendes Statement.

  3. Falls es hilft, ich möchte genau das was die da haben:
    Vorbild

    Gruß
    nachreichender
    T-Rex

  4. Soooo... nach langem tüfteln habe ich endlich eine Lösung.

    Die Lösung war zu erst die Ergebnismenge aller in Fragekommender Rezepte zu holen und dann zu gucken wie viel davon die entsprechende Eigenschaft hat.

    Das ganze sieht dann so ungefähr so aus:

    select count(*) from eigenschaften where eigenschaften_id in ( subselect aller Rezepte )

    Also im groben Jörgs Ansatz. Wobei Jörgs Ansatz für mich anfangs schwer umzusetzen war, da ein paar mehr Dateien eine Rolle spielen. Dennoch hat mir der Beispielquery geholfen umzudenken.

    Ach hierfür ein dickes Danke !

    Gruß
    Filterexperte
    T-Rex