Chris: SQL-Abfrage

Kämpfe schon seit Stunden mit folgendem SQL-Problem:

Ich habe eine Tabelle 'Tiere', die sieht so aus:

id    Gruppe    Subgruppe
-------------------------
1     Hund      Dackel
2     Hund      Terrier
3     Hund      Schaeferh
4     Katze     Wildkatze
5     Katze     Hauskatze
6     Maus      Spitzmaus

Ich möchte eine Abfrage erstellen, mit der alle in der DB vorhandenen Hauptgruppen (hier: Hund, Katze und Maus) _einmal_ herausbekomme, und zwar in der richtigen Reihenfolge (d.h. aufsteigend sortiert nach ID).
Leider überschneiden sich diese beiden Bedingungen immer bei mir:

Meine Abfrage
SELECT DISTINCT Gruppe, id FROM Tiere ORDER BY id
liefert zwar die richtige Reihenfolge, aber dafür bleiben alle Dubletten drin, weil die Kombination von Gruppe und id immer unterschiedliche Datensätze erzeugt.

Die Abfrage
SELECT DISTINCT Gruppe FROM Tiere
liefert zwar tatsächlich nur je 1x Hund, Katze und Maus - aber nicht in der richtigen Reihenfolge.

Die Lösung wäre theoretisch
SELECT DISTINCT Gruppe FROM Tiere ORDER BY id (was nicht geht, weil nur nach etwas sortiert werden kann, das aus abgefragt wurde)
oder
SELECT (DISTINCT Gruppe), id FROM Tiere ORDER BY id (was das Distinct nur auf den Gruppennamen beziehen würde. Liefert aber nur böse Fehlermeldung..)

HILFE!
Wie geht die Lösung?
Danke,
Chris

  1. Hallo,

    Ich möchte eine Abfrage erstellen, mit der alle in der DB vorhandenen Hauptgruppen (hier: Hund, Katze und Maus) _einmal_ herausbekomme, und zwar in der richtigen Reihenfolge (d.h. aufsteigend sortiert nach ID).

    Da eine Gruppe in mehreren Datensätzen vorkommt, die unterschiedliche IDs haben, mußt Du Dir überlegen, welche der ID's pro Gruppe für Dich relevant ist.

    Beispielsweise könntest Du eine Abfrage formulieren, in der nach der Spalte Gruppe gruppiert wird, wobei Du den jeweils kleinsten Wert von ID für die Sortierung verwendest. (suche dazu in Deiner Dokumentation nach GROUP BY bzw. Aggregatfunktionen).

    Andererseits ist dieses Datenbankdesign suboptimal. Besser wäre es imho, eine zweite Tabelle zu verwenden, in der die Gruppen verwaltet werden (mit ID und Bezeichnung), um dann in Deiner Tabelle nur die Gruppen-ID zu verwenden.

    Grüße
      Klaus

    1. Hi,

      Andererseits ist dieses Datenbankdesign suboptimal. Besser wäre es imho, eine zweite Tabelle zu verwenden, in der die Gruppen verwaltet werden (mit ID und Bezeichnung), um dann in Deiner Tabelle nur die Gruppen-ID zu verwenden.

      Wenn aber im Feld nur die Gruppe drinsteht und von der Gruppe keine anderen Daten mehr abhängig sind, stellt eine eineindeutige Bezeichnung ja bereits einen Eigenschlüssel dar und es besteht kein Anlass, auf zwei Tabellen aufzuteilen.

      LgadWdI

      Chris©

      1. Servus

        du musst dich bei id für min oder max entscheiden, damit kommt nur ein wert zurück und es funktioniert.
        Alternativ first oder last

        bydey

        1. Hallo zusammen.

          Danke für Eure Tips! Wenn ich mich richtig in die Materie eingelesen habe, dann laufen Eure Vorschläge alle auf folgende Lösung raus:

          SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe

          Funktioniert zwar, so daß ich jeden Gruppennamen nur einmal herausbekomme, liefert aber komischer- oder zufälligerweise die Gruppennamen in alphabetischer (d.h. falscher) Reihenfolge. Also z.B. "Hof, Hund, Katze, Maus" anstatt "Hunde, Katze, Maus, Hof".

          Gut, bin ich doch so schlau und schreib einfach noch die Sortierung dahinter:

          SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY id

          Schon kommt wieder eine Fehlermeldung: "You tried to execute a query that does not include the specified expression 'id' as part of an aggregate function."

          Ein anderer Versuch war daher, Auswahl und Sortierung in zwei Abfragen zu verschachteln:

          SELECT * FROM (SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe) ORDER BY id

          Funktioniert aber auch nicht, Fehlermeldung: "No value given for one or more required parameters." Gemeint ist damit der Parameter 'id'. Wenn ich testweise nach 'gruppe' sortieren lasse, gibts keinen Fehler.
          Ok, d.h. bei der Aggregation MIN(id) und der daraus resultierenden Tabelle scheint der Spaltenname 'id' verloren zu gehen. Gibts eine Möglichkeit, den festzulegen? Ich habe etwas gelesen von ...SELECT MIN(id)"spaltenname", gruppe...
          Leider bringt das aber auch nur einen Syntax-Fehler.

          Bin mit meinem Latein am Ende. Bitte nochmal um Eure Hilfe!
          Danke,
          Chris

          1. Hallo,

            SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY id

            Schon kommt wieder eine Fehlermeldung: "You tried to execute a query that does not include the specified expression 'id' as part of an aggregate function."

            Manche Datenbanken mögen es eher so:
            SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY MIN(id)

            Aber da Du uns bis jetzt noch nicht gesagt hast, welche Datenbank Du verwendest, kann ab jetzt nur mehr geraten werden.

            Grüße
              Klaus

            1. Manche Datenbanken mögen es eher so:
              SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY MIN(id)

              Aber da Du uns bis jetzt noch nicht gesagt hast, welche Datenbank Du verwendest, kann ab jetzt nur mehr geraten werden.

              Das ist richtig, ich bin laienhafterweise davon ausgegangen, SQL wäre eben SQL. Mußte aber feststellen, daß es ist wie im richtigen Leben: Wenn sich ein Sachse und ein Schwabe unterhalten, kann es zu Mißverständnissen kommen...
              In diesem Fall versucht eine Microsoft JET Database Engine, mit einem Access mdb-File zu kommunizieren.

              Und tatsächlich - der vorgeschlagene Weg funktioniert! DANKE!
              Auch wenn ich nicht verstehe, wie MIN(id) ein Sortierkriterium bezeichnen kann.

              Nochmals vielen Dank!
              Gruß,
              Chris

            2. Guten Morgen,

              SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY id
              SELECT MIN(id), gruppe FROM Tiere GROUP BY gruppe ORDER BY MIN(id)

              Richtig wäre es dann so:
              SELECT MIN(id) as minid, gruppe FROM Tiere GROUP BY gruppe ORDER BY minid

              Das erspart dem Datenbanksystem die nochmalige Ausführung der Funktion MIN(). Wenn das so wie oben funktioniert hat, wundert mich das sowieso.

              LGadWdI

              Chris©

              1. Hallo,

                Richtig wäre es dann so:
                SELECT MIN(id) as minid, gruppe FROM Tiere GROUP BY gruppe ORDER BY minid

                Das erspart dem Datenbanksystem die nochmalige Ausführung der Funktion MIN().

                Naja, einen Optimizer wird die Datenbank schon haben, und der sollte das an sich schon erkennen;-)

                Wenn das so wie oben funktioniert hat, wundert mich das sowieso.

                Warum wundert Dich das? MIN(spalte) ergibt einen Wert nach dem man sortieren kann. Da ist imho nichts aussergewöhnliches dabei.

                Grüße
                  Klaus

              2. Richtig wäre es dann so:
                SELECT MIN(id) as minid, gruppe FROM Tiere GROUP BY gruppe ORDER BY minid

                Hallo nochmal!
                Ich bin begeistert ob der Eleganz dieser Lösung - besten Dank dafür!
                Wie eine Zahl (MIN(id)) ein Sortierkriterium darstellen kann, habe ich auch nicht verstanden, umgehe das aber sehr schick mit dieser Variante.

                Danke nochmal,
                Chris