Alex: Migration von MySQL 3.23 -> 4.1: Problem mit Subqueries

Moin allerseits,

Ich habe durch den Wechsel von der MySQL Clientversion 3.23.49 auf 4.1.18 Probleme bekommen mit Subqueries. Ich möchte eine Liste (list_pics) mit Verweisen auf Bild-Referenzen (refs) nach bestimmten Kategorien filtern (categories + catsets).

Tabellen:
---------

refs ([id, label, path, ...] Tabelle für Bild-Referenzen)

list_pics ([entry_id, id, label, ...] referenziert mit dem Primary Key 'id' auf einen Eintrag in Tabelle 'refs')

categories ([cid, label, ...] Tabelle für Kategorien)

catsets ([cid, id] Tabelle für Zuweisungen von Bild-Referenzen (id) an Kategorien (cid))

Meine SQL-Query:

SELECT list.label, list.id, list.entry_id FROM list\_pics As list INNER JOIN refs As ref ON ref.id=list.id WHERE (
 ref.id != '163'
  AND
 (SELECT count(cat.cid) FROM catsets As catset INNER JOIN categories AS cat ON catset.cid=cat.cid WHERE catset.id=list.id AND cat.cid = '6') > 0
) ORDER BY position LIMIT 0, 1

Die erste Bedingung "ref.id != '163'" ist hier zu vernachlässigen.
Probleme gibts bei der zweiten Bedingung, der Subquery. Der Bedingung "catset.id=list.id" fehlt für "list.id" der Wert, der eigentlich aus der Hauptquery übergeben werden sollte.

Konkrete Frage: Kann es sein das seit 4.x Subqueries nicht mehr auf Spalten referenzieren können, die in der Hauptquery bestimmt werden? Und wie kann man dieses dennoch erreichen?

Vielen Dank für Eure Hilfe,

Alex

  1. echo $begrüßung;

    Ich habe durch den Wechsel von der MySQL Clientversion 3.23.49 auf 4.1.18 Probleme bekommen mit Subqueries.

    Die Client-API-Version ist für dein Problem nicht weiter relevant. Die Server-Version wäre interessanter, denn die muss den Befehl ausführen. Die Client-API reicht ihn nur durch.

    Konkrete Frage: Kann es sein das seit 4.x Subqueries nicht mehr auf Spalten referenzieren können, die in der Hauptquery bestimmt werden? Und wie kann man dieses dennoch erreichen?

    MySQL kann erst ab Version 4.1 mit Subqueries umgehen. Unter welchen Umständen man welche Werte der Haupt-Query ansprechen kann findest du im Kapitel Subquery Syntax und dessen Unterkapiteln.

    echo "$verabschiedung $name";

    1. Die Client-API-Version ist für dein Problem nicht weiter relevant. Die Server-Version wäre interessanter, denn die muss den Befehl ausführen. Die Client-API reicht ihn nur durch.

      Alter Server: (XAMPP)Apache/2.0.53 (Win32) PHP/4.3.10
      Neuer Server: Apache/1.3.36 (Unix) PHP/4.4.2

      MySQL kann erst ab Version 4.1 mit Subqueries umgehen.

      Das verwirrt mich ein wenig, da die (Sub)Queries wie beschrieben unter Version 3.23 funktionierten.

      Laut der MySQL-Referenz sind bei Correlated Subqueries Referenzierung auf die Hauptquery möglich.

      1. hi,

        Die Client-API-Version ist für dein Problem nicht weiter relevant. Die Server-Version wäre interessanter

        Alter Server: (XAMPP)Apache/2.0.53 (Win32) PHP/4.3.10
        Neuer Server: Apache/1.3.36 (Unix) PHP/4.4.2

        Auch das ist weniger interessant, denn die MYSQL-Server-Version war natürlich gefragt - wie dedlfix schon schrieb:

        denn die muss den Befehl ausführen.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Auch das ist weniger interessant, denn die MYSQL-Server-Version war natürlich gefragt

          Meine phpmyadmins sagen mir

          alt: Verbunden mit MySQL 4.1.11 auf localhost
          neu: Verbunden mit MySQL 4.1.19-standard-log auf localhost

          kann damit wer was anfangen?
          ich wüßte sonst nicht wie ich die Server-Version erfahre...

          1. Also offensichtlich werden Subqueries nicht unterstützt, was mich dazu zwingt, keine mehr einzusetzen.

            Vielleicht kann mir jmd dabei behilflich sein.
            Das Problem für mich als Nonprofi in Sachen SQL ist die Abfrage zugeordneter Kategorien:

            einem Eintrag aus Tabelle "list" können mehrere Kategorien zugeordnet sein. Wenn ich prüfen will, ob einem Listeneintrag in der Tabelle "catsets" eine oder mehrere Kategorien aus der Tabelle "categories" zugeordnet sind deren Name "ball" enthält, kann ich das bisher nur über die Subquery

            "...WHERE
            (SELECT count(cat.cid) FROM catsets As catset INNER JOIN categories AS cat ON catset.cid=cat.cid WHERE catset.id=list.id AND cat.name LIKE '%ball%') > 0"

            lösen

            Eine Lösung die nicht auch abstrakt auf anderen Datenbanksystemen (einschließlich ihrer Versionen) läuft, ist leider inakzeptabel.

            Grüße,
            Alex

            1. Hallo Alex,

              Vielleicht kann mir jmd dabei behilflich sein.
              Eine Lösung die nicht auch abstrakt auf anderen Datenbanksystemen

              Was verstehst Du unter "abstrakt" in diesem Zusammenhang? Ich verstehe dieses Wort hier nicht.

              (einschließlich ihrer Versionen) läuft, ist leider inakzeptabel.

              Dennoch fällt mir bei diesen Randbedingungen die Antwort ganz einfach:

              Es gibt nur inakzeptable Lösungen. Infolgedessen möchte ich mir nicht die Mühe machen eine zu finden. Anderen wünsche ich viel Spass beim Suchen inakzeptabler Lösungen. Ich finde bestimmt eine Version eines DBMS, auf dem die Lösung nicht läuft ...

              Könntest Du daher nicht Deine Problemstellung ändern?

              Soll Dein Problem wirklich auf der Originalversion von dBASE laufen, soll es von Access 1.0 unterstützt sein, wie relevant ist MS SQL-Server 4.21 oder Oracle 2 auf 'ner PDP-11?

              Ratlose Grüße

              Vinzenz

            2. Hallo Alex,

              einem Eintrag aus Tabelle "list" können mehrere Kategorien zugeordnet sein.

              ich nehme an, einer Kategorie können mehrere Listeneinträge zugeordnet sein?

              Wenn ich prüfen will, ob einem Listeneintrag in der Tabelle "catsets" eine oder mehrere Kategorien aus der Tabelle "categories" zugeordnet sind deren Name "ball" enthält, kann ich das bisher nur über die Subquery

              "...WHERE
              (SELECT count(cat.cid) FROM catsets As catset INNER JOIN categories AS cat ON catset.cid=cat.cid WHERE catset.id=list.id AND cat.name LIKE '%ball%') > 0"

              lösen

              Deine Beschreibung ist übrigens ziemlich unverständlich. Du hättest deutlich bessere Aussichten auf Hilfe, wenn Du ein paar Beispieldatensätze liefern würdest und dazu die von Dir gewünschte Ergebnismenge mit der Begründung, warum Du genau diese haben möchtest.

              Freundliche Grüße

              Vinzenz

              1. Hallo Ingrid,

                "...WHERE
                (SELECT count(cat.cid) FROM catsets As catset INNER JOIN categories AS cat ON catset.cid=cat.cid WHERE catset.id=list.id AND cat.name LIKE '%ball%') > 0"

                soweit ich das allmählich überblicke, sollten es DISTINCT und ein paar INNER JOINs es doch tun. Ein inakzeptabler Lösungsversuch:

                SELECT DISTINCT  
                    list.label,  
                    list.id,  
                    list.entry_id  
                FROM `list_pics` list    -- AS versteht nicht jedes aktuelle DBMS :-)  
                INNER JOIN refs ref      -- Wo ist da der echte Nutzen des Alias?  
                ON ref.id = list.id  
                INNER JOIN catsets cs  
                ON ref.id = cs.id  
                INNER JOIN categories c  
                ON cs.cid = c.cid  
                WHERE ref.id != '163'          -- Deine irrelevante Bedingung  
                    AND cs.cid = '6'           -- die gesuchte Kategorie  
                    AND c.name LIKE '%ball%'   -- die zulässigen Namen  
                )  
                ORDER BY position  
                LIMIT 1                        -- was nicht jedes DBMS versteht
                

                Versagt schon einmal bei MS SQL-Server, Oracle, MS Access, selbst den derzeit aktuellen Versionen :-)
                Wenn Du es wirklich DB-unabhängig haben willst, so nutze einen Querybuilder eines Datenbankabstraktionslayers einer API, der sämtliche existierenden DBMS-Versionen unterstützt.

                Freundliche Grüße

                Vinzenz

  2. echo $begrüßung;

    Probleme gibts bei der zweiten Bedingung, der Subquery. Der Bedingung "catset.id=list.id" fehlt für "list.id" der Wert, der eigentlich aus der Hauptquery übergeben werden sollte.

    Nun, nachdem die Versionsfrage geklärt ist, und du auch mit Hilfe des Handbuchkapitels Subquery Syntax noch nicht die Lösung gefunden hast, kommen wir nun zur alles entscheidenden Frage: Um was für ein Problem handelt es sich überhaupt?

    Mit meiner kleinen ähnlich gestalteten Test-Abfrage (Joins hab ich weggelassen) konnte ich mit Version 4.1.19 kein Problem mit der Subquery erkennen.

    Im Anhang gibt es übrigens auch noch ein Kapitel zu Restrictions on Subqueries.

    echo "$verabschiedung $name";