ERROR: column "number" does not exist

Hallo,

bei einer simplen Abfrage mitttels des Query-Tools von PGAdmin


SELECT          count(*) AS number, 
                filename
FROM            Midifan.Midi
WHERE           number > 1
GROUP BY        filename
ORDER BY        number DESC;

bekomme ich die Fehlermeldung

ERROR:  column "number" does not exist

Interessanterweise liefert mir der folgende Code keine Fehlermeldung:

SELECT          count(*) AS number, 
                filename
FROM            Midifan.Midi
GROUP BY        filename
ORDER BY        number DESC;

Also “ORDER BY” kennt “number” als Spaltename und “WHERE” kennt ihn nicht!



Bin ich nun betriebsblind (habe ich etwas übersehen) oder ist das ein BUG?



mfg

fristo

tag

hast du schon mal versucht das feld number beim vergleich in “” zu schreiben ?
evtl versucht er im WHERE teil das feld als funktion oder datentyp zu interpretieren und im ORDER BY teil nicht.

mfg
henrik

Hallo henrik,

ich hatte bereits alle Möglickeiten, auch die Du beschrieben hast, ausgetestet. Aber die Fehlermeldung kommt immer wieder!

Also doch ein BUG?



mfg

fristo

Was is eigentlich das Midifan.Midi ? ne tabelle ? ne view ? ( könntest du mal die struktur posten ? würd ich auch gern mal testen) aber sollte die abfrage einer aggregat funktion nicht im HAVING statt im WHERE stehen ?

SELECT count(*) AS number,
filename
FROM Midifan.Midi
GROUP BY filename
HAVING number > 1
ORDER BY number DESC;

und wenn das nicht klappt wegen dem bezeichner sollte das auf jedenfall gehn:

SELECT count() AS number,
filename
FROM Midifan.Midi
GROUP BY filename
HAVING count(
) > 1
ORDER BY count(*) DESC;

mfg
henrik

Hallo henric,

war doch Betriebsblindheit!

SELECT          count(*) AS number, 
                filename 
FROM            Midifan.Midi 
GROUP BY        filename 
HAVING          count(*) > 1 
ORDER BY        count(*) DESC;

wie auch

SELECT          filename
FROM            Midifan.Midi
GROUP BY        filename
HAVING          count(*) > 1;

funktioniert einwandfrei. Wobei die Schreibweise count(*) für mich schon etwas eigenartig ist, aber auch die Schreibeweise count(filename) funktioniert.



Dann wird das ganze mit

SELECT          *
FROM            Midifan.Midi
GROUP BY        filename
HAVING          count(filename) > 1;

und der Fehlermeldung

ERROR:  column "midi.titel" must appear in the GROUP BY clause or be used in an aggregate function

wieder unverständlich, weil nach dem folgeden verlangt wird

SELECT          *
FROM            Midifan.Midi
GROUP BY        filename,
                titel,
                artist
HAVING          count(filename) > 1;

und sich count(…) default mäßig immer auf den ersten Eintrag von GROUP BY bezieht. Die Sortierung nach “titel” und “artist” ist weder verlangt noch notwendig und kostet nur Zeit. Hier kann man PostgreSQL also noch optimieren!



Zu Deiner Frage: “Midifan” ist das SCHEMA, in der die TABELLE “Midi” angelegt wurde.

Hier noch Kode zum Testen:

-- DROP TABLE      midifan.midi;

CREATE TABLE    midifan.midi
                (
                filename        VARCHAR(100)    NOT NULL,
                titel           VARCHAR(100)    DEFAULT NULL,
                artist          VARCHAR(100)    DEFAULT NULL
                ); 



INSERT INTO     midifan.midi VALUES ('A0.mid', '0', '3');

INSERT INTO     midifan.midi VALUES ('A1.mid', '1', '4');
INSERT INTO     midifan.midi VALUES ('A1.mid', '1', '4');

INSERT INTO     midifan.midi VALUES ('A2.mid', '2', '5');
INSERT INTO     midifan.midi VALUES ('A2.mid', '2', '5');



SELECT          filename
FROM            midifan.midi
GROUP BY        filename
HAVING          count(*) > 1; 



SELECT          *
FROM            midifan.midi
GROUP BY        filename,
                titel,
                artist
HAVING          count(filename) > 1;

Wenn Du “midifan.” aus dem Kode ersatzlos löscht, wird die Tabelle im Schema “public” angelegt.



mfg

fristo

Der fehler
ERROR: column “midi.titel” must appear in the GROUP BY clause or be used in an aggregate function

Erscheint, weil, wenn nix spezielles angegeben wird irgendein zufälliger wert in der gruppe zurück gegeben wird, was z.B. bei mysql gemacht wird.

Postgres ist da um einiges strikter, deshalb muss du die benötigten felder in einer aggregatfunktion angeben, wenn du nicht nach den werten gruppieren wills(was du in dem beispiel glaub ich nicht willst). Ich benutze da meistens MIN() wenn ich nix spezielles brauche.

SELECT          MIN(titel) as titel,MIN(artist) as artist
FROM            Midifan.Midi
GROUP BY        filename
HAVING          count(*) > 1
ORDER BY        count(*) DESC;

zu dem count(*): Ich weis leider nicht wies in postgres ist, aber in mysql wars etwas schneller als wenn man eine spalte angibt.

mfg
henrik

Hallo henric

der Kode

SELECT          * 
FROM            midifan.midi 
GROUP BY        filename, 
                titel, 
                artist 
HAVING          count(*) > 1
ORDER BY        count(*);

funktioniert und er funktioniert auch wenn ich alle Felder angebe

SELECT          filname, 
                titel, 
                artist 
FROM            midifan.midi 
GROUP BY        filename, 
                titel, 
                artist 
HAVING          count(*) > 1
ORDER BY        count(*);

Das gelieferte Ergebnis ist das gleiche.

Vielleicht hast Du mich missverstanden. Die Frage, die sich stellt, heißt ganz einfach: Warum wird noch die Sortierung nach “titel” und “artist” verlangt, wenn sie nicht notwendig und nicht gewollt ist. Die nicht notwendige und nicht gewollte Sortierung benötigt also nur zusätzliche Zeit. Denk mal an große Tabellen oder an Tabellen, die z.B. 50 Spalten haben.



mfg

fristo

Group by sortiert ja nicht einfach, sondern gruppiert danach.

Wenn du also z.B. nur nach artist gruppierst

bei den daten:
titel artist filename
song1 mr1 lied1.mp3
song2 mr1 lied2.mp3

erhältst du mit GROUP BY artist,filename,titel die daten:
song1 mr1 lied1.mp3
song2 mr1 lied2.mp3
zurück

mit GROUP BY artist
nur einen datensatz, aber postgres weis ohne aggregatfunktionen nicht, welchen song und welches lied es zurückgeben soll.

song? mr1(danach ist ja gruppiert) lied?.mp3

deshalb musst du in postgres, auch wenn es nicht mehrere titel und filenames gibt in einer aggregat funtkion angeben, welches nicht gruppierte feld genommen werden soll, falls doch mehrere gefunden werden.
select MIN(titel),artist,MIN(filename) mit GROUP BY artist
gibt dann folgendes zurück:
song1 mr1 lied1.mp3


mfg
henrik