Problem mit SQL-Abfrage
Bobby
- datenbank
0 Ilja0 Bobby1 Vinzenz Mai
Moin
Ich seh den Wald vor lauter Bäumen nicht.
meine Abfrage lautet:
SELECT * , buchungen.anzahl AS buchungenanzahl
FROM belegungen
LEFT JOIN buchungen ON ( buchungen.roomid = 1
AND buchungen.buchstart <= '1216872001'
AND buchungen.buchend >= '1216872001' )
WHERE belegungen.kontingent > buchungenanzahl
LIMIT 0 , 30
Warum ist "buchungenanzahl" eine unbekannte Spalte?
MEldung: #1054 - Unknown column 'buchungenanzahl' in 'where clause'
Kann mir jemand helfen? Bin ich einfach nur blind? Oder ist es einfach nur zu spät?
Gruß Bobby
yo,
Warum ist "buchungenanzahl" eine unbekannte Spalte?
weil nicht jedes dbms mit aliasnamen in der where klausel arbeitet. benutze den richtigen spaltennamen buchungen.anzahl und es wird gehen.
Ilja
Moin
weil nicht jedes dbms mit aliasnamen in der where klausel arbeitet. benutze den richtigen spaltennamen buchungen.anzahl und es wird gehen.
Ok. Und wie kann ich folgende Abfrage gestalten? Dort erscheint ebenfalls der genannte Fehler:
SELECT * , SUM(buchungen.anzahl) AS buchungenanzahl
FROM belegungen
LEFT JOIN buchungen ON ( buchungen.roomid = 1
AND buchungen.buchstart <= '1216872001'
AND buchungen.buchend >= '1216872001' )
WHERE belegungen.kontingent > buchungenanzahl
LIMIT 0 , 30
Bei dieser Abfrage möchte ich alle Buchungen für ein bestimmtes Zimmer zusammenzählen und nur die Zimmer ausgegeben erhalten, die noch nicht ausgebucht sind (SUMME belegungen kontingent > buchungenanzahl) Ich hoffe ich habe mich verständlich ausgedrückt. Weißt du auch dafür ne Lösung?
Gruß Bobby
Hallo Bobby,
weil nicht jedes dbms mit aliasnamen in der where klausel arbeitet. benutze den richtigen spaltennamen buchungen.anzahl und es wird gehen.
Ok. Und wie kann ich folgende Abfrage gestalten? Dort erscheint ebenfalls der genannte Fehler:
das ist viel schlimmer. Sowas akzeptiert nur MySQL. Jedes andere DBMS wirft vernünftigerweise mit Fehlermeldungen um sich.
SELECT * ,
Raus mit SELECT *. Das geht hier nicht. Du musst schließlich nach _jeder_ einzelnen Spalte gruppieren, auf die keine Aggregatsfunktion angewandt wird. Somit musst Du sowieso jede Spalte aufführen.
Welche Details Du dort haben willst, ist natürlich wichtig - und es kann sein dass Du dafür eine korrelierte Unterabfrage benötigst. Für korrelierte Subselects findest Du im Archiv viele viele Beiträge, oft von Ilja oder mir :-)
SUM(buchungen.anzahl) AS buchungenanzahl
WHERE belegungen.kontingent > buchungenanzahl
Weißt du auch dafür ne Lösung?
Dafür gibt es die HAVING-Klausel. In der darfst Du (in MySQL) sogar Spaltenaliasnamen verwenden.
Ein paar Beispieldatensätze und das gewünschte Ergebnis wären ganz nett. Sowas hilft viel mehr als falsche SQL-Statements.
Freundliche Grüße
Vinzenz
Moin
OK. Also eine nähere Erklärung:
ich habe 2 Tabellen
Belegungen (Belegungspan)
id | buchstart | buchend | kontingent | roomid
1 | timestamp | timestamp | 3 | 1
Diese Tabelle enthält Belegungskontingente für bestimmte Zimmer und bestimmte Zeiträume
Als 2 Tabelle gibt es buchungen
id | buchstart | buchend | anzahl | roomid
1 | timestamp | timestamp | 1 | 1
2 | timestamp | timestamp | 1 | 1
nun möchte ich die Buchungen für ein Zimmer in einer bestimmten Zeit zusammenzählen. Deswegen SUM(buchungen.anzahl) AS buchungenanzahl WHERE roomid =1
Die Zusammengezählte Anzahl möchte ich mit dem Kontingent in der TAbelle Belegungen vergleichen (WHERE belegungen.kontingent > buchungenanzahl
Da ich gern optimal arbeiten möchte, will cih beides in einer Abfrage erfassen. Es hat auch schon mal funktioniert. Aber leider bekomm ich nicht raus warum es jetzt nicht funktioniert.
Ich hoffe die Erklärung war ausreichend.
Danke schonmal
Gruß Bobby
Hallo
ich habe 2 Tabellen
Belegungen (Belegungspan)
id | buchstart | buchend | kontingent | roomid
1 | timestamp | timestamp | 3 | 1Diese Tabelle enthält Belegungskontingente für bestimmte Zimmer und bestimmte Zeiträume
Als 2 Tabelle gibt es buchungen
id | buchstart | buchend | anzahl | roomid
1 | timestamp | timestamp | 1 | 1
2 | timestamp | timestamp | 1 | 1
Aha, verdammt wenig Datensätze, um ein sinnvolles Ergebnis zu zeigen.
Machst Du auch nicht. Schlecht!
Der seltsame Wert "timestamp" hilft natürlich ebenfalls nicht weiter. Gib konkrete Daten an.
nun möchte ich die Buchungen für ein Zimmer in einer bestimmten Zeit zusammenzählen. Deswegen SUM(buchungen.anzahl) AS buchungenanzahl WHERE roomid =1
Ja, ja. In welcher Zeit? Gib genügend Datensätze mit konkreten Daten an, damit Du genau sagen kannst, welche Du haben willst. Damit auch ein paar Datensätze ausgefiltert werden. SQL ist noch nicht gefragt. Hatte ich doch betont.
Die Zusammengezählte Anzahl möchte ich mit dem Kontingent in der TAbelle Belegungen vergleichen (WHERE belegungen.kontingent > buchungenanzahl
kein SQL. Konkrete Ergebnisse. Wo sind die? Ich sehe keine!
Da ich gern optimal arbeiten möchte, will cih beides in einer Abfrage erfassen. Es hat auch schon mal funktioniert. Aber leider bekomm ich nicht raus warum es jetzt nicht funktioniert.
Der Quatsch mit SELECT * _kann_ nicht funktioniert haben, der hat bestenfalls zufällig gefunzt[tm].
Ich hoffe die Erklärung war ausreichend.
Nein! Es ist ein Ansatz, mehr leider nicht.
Freundliche Grüße
Vinzenz
Moin
Welche Details Du dort haben willst, ist natürlich wichtig - und es kann sein dass Du dafür eine korrelierte Unterabfrage benötigst. Für korrelierte Subselects findest Du im Archiv viele viele Beiträge, oft von Ilja oder mir :-)
Danke, das scheint der Tip gewesen zu sein den ich brauchte. Ich habe nun folgende Abfrage:
SELECT *
FROM belegungen
WHERE belegungen.roomid=1
AND
belegungen.kontingent > (
SELECT SUM( buchungen.anzahl ) AS buchungenanzahl
FROM buchungen
WHERE buchungen.roomid =1 )
AND buchungen.buchstart <= '1216872001'
AND buchungen.buchend >= '1216872001'
LIMIT 0 , 30
Obs 100%ig funktioniert weiß ich erst morgen. heut ist es zu spät. Was denkst du? Sieht doch richtig so aus. Zumindest wird vom MySQL das gewünschte Ergebnis gezeigt. Datensatz aus der Tabelle Belegungen im gesuchten Zeitraum mit der gesuchten roomid und weniger Buchungen als das Kontingent.
Danke vielmals
Gruß Bobby
Hallo Bobby,
Welche Details Du dort haben willst, ist natürlich wichtig - und es kann sein dass Du dafür eine korrelierte Unterabfrage benötigst. Für korrelierte Subselects findest Du im Archiv viele viele Beiträge, oft von Ilja oder mir :-)
SELECT
bl.spaltenliste -- * ist böse[tm]
FROM
belegungen bl
WHERE
bl.kontingent > (
SELECT
SUM( bu.anzahl )
FROM
buchungen bu
WHERE
bu.roomid = bl.roomid -- das bewirkt die Korrelation
)
AND
bl.roomid = 1
AND
bl.buchstart <= '1216872001' -- das geht besser
AND
bl.buchend >= '1216872001' -- mit DATETIME
Es ist keine gute Idee, für Datums- und Zeitangaben \_nicht\_ den Datentyp DATETIME zu verwenden.
Freundliche Grüße
Vinzenz
Moin
Ok Danke....
SELECT
bl.spaltenliste -- * ist böse[tm]
Wieso böse?
> Es ist keine gute Idee, für Datums- und Zeitangaben \_nicht\_ den Datentyp DATETIME zu verwenden.
Ich weiß. Mir fällt aber die Bearbeitung mit unix-Teimestamp leichter.
Gruß Bobby
--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
-> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
Mahlzeit Bobby,
SELECT
bl.spaltenliste -- * ist böse[tm]
>
> Wieso böse?
Weil Du damit u.U. Spalten ausliest und Dir vom DBMS geben lässt, die Du gar nicht brauchst (und damit überflüssige Datenmengen übertragen werden müssen) und Du nicht weißt, welche Spalten genau Du nun eigentlich bekommst (oder kennst Du auch nach Monaten noch alle Tabellen Deiner Applikationen auswendig?) ...
> > Es ist keine gute Idee, für Datums- und Zeitangaben \_nicht\_ den Datentyp DATETIME zu verwenden.
>
> Ich weiß. Mir fällt aber die Bearbeitung mit unix-Teimestamp leichter.
Welche Bearbeitung? Deinem hingegen DBMS fällt die Bearbeitung leichter, wenn Du dessen Datums- und Zeitformate und -funktionen benutzt - und allein DAS ist maßgeblich! Was mit irgendwelchen Oberflächen besser oder einfacher ist, ist absolut irrelevant.
MfG,
EKKi
--
sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
hi EKKi,
SELECT
bl.spaltenliste -- * ist böse[tm]
> >
> > Wieso böse?
> Weil Du damit u.U. Spalten ausliest und Dir vom DBMS geben lässt, die Du gar nicht brauchst (und damit überflüssige Datenmengen übertragen werden müssen)
Bevor ich da was durcheinander schmeisse, war nicht `SELECT *`{:.language-php} die Abfrage, die alle Spalten ausliest?
Ich schreibe mittlerweile auch nur noch wie im obigen Beispiel.
~~~php
"SELECT
head.my_title, head.my_description
FROM head"
Ist das falsch?
mfg
echo $begrüßung;
Es ist keine gute Idee, für Datums- und Zeitangaben _nicht_ den Datentyp DATETIME zu verwenden.
Ich weiß. Mir fällt aber die Bearbeitung mit unix-Teimestamp leichter.
Wenn du Daten außerhalb MySQLs in einem anderen Format besser verarbeiten kannst, dann lass sie dir doch umwandeln. Gerade für Unix-Timestamps gibt es die Umwandlungsfunktionen UNIX_TIMESTAMP() und FROM_UNIXTIME(). Damit hast du mit einem kleinen Mehraufwand beim Eintragen und Abfragen auf beiden Seiten die Datein in ihrem jeweils nativen Format vorliegen. (Abgesehen davon, dass der Unix-Timestamp einen deutlich eingeschränkteren Wertebereich hat.) Obendrein kennt MySQL die Formatierfunktion DATE_FORMAT(), mit denen in vielen Anwendungsfällen der Datums- und Zeitwert gleich passend formatiert ausgegeben werden kann.
echo "$verabschiedung $name";