portseven: SQL Select in Select (oder 2x Count in einem SQL)

Tag,

Tut mir leid das ich schon wieder nen Beitrag erstelle und ich euch nerve aber bin halt fleißig am lernen und benötige dazu auch öfters Hilfe<.<

Zu meiner Frage:

Ich möchte in meinem SQL Befehl nochmal einen Count hinzufügen. Wie kann ich das am besten machen? Hab UNION ausprobiert oder nochmal (SELECT) in klammern aber bekomme nur Fehler wo das hier steht: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right synta

Ich möchte dies gerne hinzufügen: COUNT(u_post_likes_comment) AS like in diesem SQL Befehl

Hat einer von euch eventuell ne Ahnung wie ich das jetzt mache?

	$stmt = $pdo->prepare("SELECT 
    u_post.p_id, 
    u_post.u_id,  
    u_post.p_like,  
    u_post.p_heart,  
    u_post.post, 
    u_post.image_ordner, 
    u_post.date, 
	
    user.id, 
    user.username, 
    user.name, 
    user.nachname, 
    user.image,
	
	
	COUNT(u_post_likes.id) AS likes,
	u_post_likes.post_id,
	u_post_likes.user AS newid,
	
	follow.user_id,
	follow.follow_id
    FROM u_post 

	LEFT JOIN user
	ON u_post.u_id = user.id
	
	LEFT JOIN u_post_likes
	ON u_post.p_id = u_post_likes.post_id
	
	LEFT JOIN u_post_likes_comment
	ON u_post_likes_comment.user = user.id
	
	
	LEFT JOIN follow
	ON user.id = follow.follow_id OR user.id = follow.user_id 

	WHERE follow.user_id = :user_id

	GROUP BY u_post.p_id

    ORDER BY date DESC
	
	"); 
  1. Tach!

    Tut mir leid das ich schon wieder nen Beitrag erstelle und ich euch nerve aber bin halt fleißig am lernen und benötige dazu auch öfters Hilfe<.<

    Kein Problem.

    Ich möchte dies gerne hinzufügen: COUNT(u_post_likes_comment) AS like in diesem SQL Befehl

    LIKE ist ein reserviertes Wort. Du musst es in Anführungszeichen einschließen, wenn du es in deinem Sinne verwenden möchtest.

    dedlfix.

    1. Hallo dedlfix,

      er hat das s ja nur nicht kopiert; im Code-Beispiel steht likes. Sein Kopierer scheint ein Loch zu haben, da sind noch mehr Buchstaben durchgeflutscht.

      Hallo portseven,

      die Meldung müsste eigentlich ETWAS aufschlussreicher sein, aber zum Prinzip von SQL folgendes: COUNT ist eine Aggregat-Funktion. Solche Funktionen laufen über alle Sätze, für die die GROUP BY Klausel den gleichen Wert ergibt. Bei Dir also alle Sätze mit gleichem Wert für u_post.p_id.

      Setzt man GROUP BY ein, hat man im SELECT zwei Möglichkeiten. Entweder man verwendet Spalten, die im GROUP BY benannt sind (weil es für die einen eindeutigen Wert gibt), oder man wendet eine Aggregatfunktion auf andere Spalten an. Folgendes Statement ist nicht erlaubt:

      SELECT foo, bar, COUNT(baz)
      FROM tabloid
      GROUP BY foo
      

      weil der GROUP BY sagt: Liefere mir eine Zeile pro gefundenem Wert von foo; und es ist ja möglich, dass es zwei Zeilen gibt, wo foo gleich ist aber bar nicht. Du hast also keinen eindeutigen Wert für bar. Deswegen ist das falsch.

      Das hier ist korrekt:

      SELECT foo, bar, COUNT(baz)
      FROM tabloid
      GROUP BY foo, bar
      

      Bei Dir ist das nur lästig, weil Du eine Menge Spalten selektierst. Die müssten alle im GROUP BY stehen, damit COUNT funktioniert.

      Ob ein Subselect SINNVOLL ist, muss man schauen. Was willst Du zählen? Alle Likes, die ein Benutzer abgesetzt hat, oder alle Likes, die ein Kommentar bekommen hat?

      Rolf

      --
      sumpsi - posui - clusi
      1. Hallo,

        Hallo dedlfix,

        er hat das s ja nur nicht kopiert; im

        Das dachte ich zuerst auch. Aber dedlfix hat das Problem m.E. richtig erkannt. Im code ist ja nur ein count vorhanden und im betreff geht es um ein zweites.

        Gruß
        Kalk

        1. Hallo Tabellenkalk,

          da hast Du recht und ich habe gemüllt. Heute ist offenbar nicht mein Tag 😉

          Dann frage ich mich aber warum die Query überhaupt funktioniert - gilt in MySQL / MariaDB die SQL Einschränkung nicht, dass bei GROUP BY nur solche Felder unaggregiert im SELECT stehen dürfen, die zum Gruppieren verwendet wurden?

          Rolf

          --
          sumpsi - posui - clusi
          1. Tach!

            Dann frage ich mich aber warum die Query überhaupt funktioniert - gilt in MySQL / MariaDB die SQL Einschränkung nicht, dass bei GROUP BY nur solche Felder unaggregiert im SELECT stehen dürfen, die zum Gruppieren verwendet wurden?

            Genau die gilt nicht, wenn man nicht in einen bestimmten standard-kompatiblem Modus schaltet

            dedlfix.

          2. Vielen dank euch erstmal. Habe es hinbekommen.

            Zu Group_By.

            Ich bekomme keinerlei Fehler auch wenn ich nicht alles selektiert habe & alles läuft reibungslos.

            1. Tach!

              Zu Group_By.

              Ich bekomme keinerlei Fehler auch wenn ich nicht alles selektiert habe & alles läuft reibungslos.

              Ja, das ist eine Besonderheit bei MySQL, dass das so geht. Aber du solltest wissen, dass aus gutem Grund andere DBMSe ein Group-By-Konstrukt nur gestatten, wenn nur die gruppierten Felder zuzüglich Aggregatsfunktionen (SUM, COUNT, AVG, etc.) im Select verwendet werden. MySQL hingegen nimmt sich bei anderen Feldern den Inhalt eines beliebigen Datensatzes. Es ist nicht garantiert, dass es immer der Datensatz ist, den du im Test siehst. Reibungslos geht das also nur, wenn alle diese Feldinhalte in der Gruppe redundant/gleich sind.

              Statt eines Joins, das ein kartesisches Produkt erzeugt, das du mit GROUP BY wieder einkürzt, kann man Correlated Subquerys nehmen. Vor allem dann, wenn man von der Subquery nur einen einzelnen Wert benötigt. Bei mehreren Werten kann man in Erwägung ziehen, die Subquery ins FROM/JOIN zu schreiben und sie dort auf eine Ergebniszeile pro Hauptquery einzudampfen, so dass ebenfalls das unnötige kartesische Produkt vermieden wird.

              dedlfix.

              1. Hallo dedlfix,

                Bei mehreren Werten kann man in Erwägung ziehen, die Subquery ins FROM/JOIN zu schreiben und sie dort auf eine Ergebniszeile pro Hauptquery einzudampfen, so dass ebenfalls das unnötige kartesische Produkt vermieden wird.

                Zu bemerken wäre noch, dass man in dem Fall einen LEFT JOIN verwenden sollte, weil man sonst bei einem Nichttreffer der Subquery gar kein Ergebnis mehr bekommt.

                Bei mehreren Werten aus der Subquery wäre "kann" für mich das falsche modale Hilfswerb; ich würde "muss" einsetzen. Denn sonst führt man die Subquery redundant mehrfach aus. Der Server optimiert das möglicherweise weg, aber die Redundanz beim Schreiben, inclusive der Fehleranfälligkeit beim Ändern, bleibt.

                Die Frage nach dem Eindampfen stellt sich hoffentlich gar nicht erst, denn wenn die Abfrage Kandidat für eine correlated Subquery war, dann hat man ja sowieso nur einen Treffer erwartet bzw. hätte andernfalls vom SQL Server zur Ausführungszeit eine Watschn bekommen. Oder ist MySQL da AUCH wieder anders?!?!

                Rolf

                --
                sumpsi - posui - clusi
                1. Tach!

                  Die Frage nach dem Eindampfen stellt sich hoffentlich gar nicht erst, denn wenn die Abfrage Kandidat für eine correlated Subquery war, dann hat man ja sowieso nur einen Treffer erwartet bzw. hätte andernfalls vom SQL Server zur Ausführungszeit eine Watschn bekommen. Oder ist MySQL da AUCH wieder anders?!?!

                  Wenn du eine Subquery ins FROM/JOIN steckst, die mehrere Datensätze pro Hauptquery liefert, oder auch die ohne Zusammenhang zur Hauptquery Datensätze liefert, dann entstehen da kartesische Produkte in der selben Form, wie es auch bei einfachen Tabellenreferenzen der Fall wäre. Eventuelle Join-Bedingungen werden natürlich berücksichtigt. Was für eine Watschn wäre denn da zu erwarten, oder meinst du was anderes?

                  dedlfix.

                  1. Hallo dedlfix,

                    müsste ich mal ausprobieren. Ich würde einen SQLCode erwarten: "Mehrere Treffer bekommen, einen erwartet".

                    Rolf

                    --
                    sumpsi - posui - clusi
                    1. Tach!

                      müsste ich mal ausprobieren. Ich würde einen SQLCode erwarten: "Mehrere Treffer bekommen, einen erwartet".

                      Das gibt es nur in der SELECT-Klausel, da wird exakt ein einzelner Wert aus einer Subquery erwartet. Im FROM hingegen kann MySQL und andere Systeme immer ein kartesisches Produkt aus den Mengen bilden.

                      dedlfix.