Bobby: Problem mit SQL-Abfrage

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

--
-> 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:)
  1. 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

    1. 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

      --
      -> 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:)
      1. 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

        1. 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

          --
          -> 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:)
          1. Hallo

            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

            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

        2. 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

          --
          -> 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:)
          1. 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
            
            1. 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:)
              
              1. 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:|
                
                1. 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

              2. 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";