Immi: Frage zu SQL Query

Hallo zusammen!

Ich hab mir ein Query geschrieben, dass leider nicht die gewünschten Ergebnisse liefert. Jetzt wollte ich Fragen, ob ich es überhaupt so lösen kann, oder ob ich hier auf dem falschen Weg bin?

Ich möchte aus einer Restaurant Datenbank einige dinge selektieren, die ich am besten kurz beschreibe:

  • Wenn d.FlOffen = -1 ist, dann ist der Kellner Anwesend und arbeitet gerade, mit COUNT möchte ich auf die Anzahl anwesender Kellner kommen.

  • d1.brulohn (Lasst euch hier vom Spaltennamen nicht verwirren) ist der Betrag, den ein Kellner pro Stunde kostet, also z.b. 50.- Hier möchte ich den Durchschnittsbetrag aller anwesenden Kellner selektieren.

  • In der Tabelle Bon werden alle gebuchten Artikel angezeigt. d2.PosWert ist der Umsatz, also BezogeneMenge*Verkaufspreis und davon möchte ich die Summe.

  • als SummeEK möchte ich die Summe des Einkaufspreises aller verkauften Artikel. d3.ekakt ist der aktuelle Einkaufspreis des Artikels und d2.Menge, die Menge.

  • Desweiteren möchte ich nur die Daten, die während der letzten Stunde generiert wurden, dass wollte ich mit "(DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)" machen. d2.BonDat ist das genaue Datum und die Genaue Zeit, wann der Artikel gebucht wurde.

Ich hoffe ich konnte Euch mein Problem schildern und möchte mich bereits jetzt für Eure Hilfe bedanken!

Freundliche Grüsse
Immi

SELECT COUNT(d.FlOffen)        AS AnzKellner,
       AVG(d1.brulohn)         AS DurchschnittBruLohn,
       SUM(d2.PosWert)         AS SummeUmsatz,
       SUM(d3.ekakt*d2.Menge)  AS SummeEK

FROM
    dbo.ZeitBuchung    d,
    dbo.Kellner        d1,
    dbo.Bon            d2,
    dbo.Arti           d3

WHERE
     d.FlOffen  = '-1'
AND  d.kellnr   = d1.Kellnr
AND d3.artnr    = d2.artnr
AND (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

  1. Mahlzeit,

    FROM
        dbo.ZeitBuchung    d,
        dbo.Kellner        d1,
        dbo.Bon            d2,
        dbo.Arti           d3

    WHERE
         d.FlOffen  = '-1'
    AND  d.kellnr   = d1.Kellnr
    AND d3.artnr    = d2.artnr
    AND (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

    Wie hängen d und d1 einerseits und d2 und d3 andererseits zusammen? Ich kann da keinen Zusammenhang erkennen. Außerdem wäre es ratsam (und sorgt für mehr Übersichtlichkeit), wenn du sprechende Aliasnamen vergeben und explizite JOINs nutzen würdest.

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Mahlzeit,

      FROM
          dbo.ZeitBuchung    d,
          dbo.Kellner        d1,
          dbo.Bon            d2,
          dbo.Arti           d3

      WHERE
           d.FlOffen  = '-1'
      AND  d.kellnr   = d1.Kellnr
      AND d3.artnr    = d2.artnr
      AND (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

      Wie hängen d und d1 einerseits und d2 und d3 andererseits zusammen? Ich kann da keinen Zusammenhang erkennen. Außerdem wäre es ratsam (und sorgt für mehr Übersichtlichkeit), wenn du sprechende Aliasnamen vergeben und explizite JOINs nutzen würdest.

      MfG,
      EKKi

      Hallo EKKi

      Zeitbuchung d, und Kellner d1 hängen mit den Kellnr zusammen. In der Zeitbuchung ist ja drin, ob ein Kellner anwesend ist oder nicht (d.FlOffen) und in der Kellner Tabelle d1 ist dann der d1.brulohn, also der Betrag, den der Kellner pro Stunde kostet. Ich möcht ja dann nur die KellnerkostenProStunde von den Kellnern, die anwesend sind..

      Ja, Joins hab ich nicht sooo im Griff und bei nem komplexeren Query lass ich die lieber weg, weil ich dann den Durchblick noch mehr verliere. Wäre aber für Vorschläge immer Dankbar!

      lg
      Immi

      1. Mahlzeit,

        Zeitbuchung d, und Kellner d1 hängen mit den Kellnr zusammen. In der Zeitbuchung ist ja drin, ob ein Kellner anwesend ist oder nicht (d.FlOffen) und in der Kellner Tabelle d1 ist dann der d1.brulohn, also der Betrag, den der Kellner pro Stunde kostet.

        Das ist mir schon klar. Aber es gibt keine Verbindung zwischen den beiden zusammenhängenden Tabellen d und d1 auf der einen und d2 und d3 auf der anderen Seite ... insofern ist's kein Wunder, wenn bei der Abfrage viel zu viele nicht zusammensammengehörende Daten herauskommen.

        Ja, Joins hab ich nicht sooo im Griff und bei nem komplexeren Query lass ich die lieber weg, weil ich dann den Durchblick noch mehr verliere. Wäre aber für Vorschläge immer Dankbar!

        Lass es dir aus eigener Erfahrung gesagt sein: INSBESONDERE bei komplexeren Abfragen sind explizite JOINs weitaus einfacher zu durchschauen - hauptsächlich weil sofort klar wird, wie welche Tabellen zusammenhängen und sich in der WHERE-Einschränkung nur noch inhaltliche Dinge befinden.

        -----8<-----8<-----8<-----

        SELECT [...]
          FROM dbo.ZeitBuchung d
          JOIN dbo.Kellner     d1 ON d.kellnr = d1.Kellnr
          JOIN dbo.Bon         d2 ON /* ??? */
          JOIN dbo.Arti        d3 ON d2.artnr = d3.artnr
         WHERE d.FlOffen  = '-1'
           AND (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

        ----->8----->8----->8-----

        Spätestens wenn man deine Query so umschreibt, wird klar, was ich meine: es fehlt die Verknüpfung der Tabelle d2 mit dem Rest ...

        MfG,
        EKKi

        --
        sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
        1. Mahlzeit,

          Zeitbuchung d, und Kellner d1 hängen mit den Kellnr zusammen. In der Zeitbuchung ist ja drin, ob ein Kellner anwesend ist oder nicht (d.FlOffen) und in der Kellner Tabelle d1 ist dann der d1.brulohn, also der Betrag, den der Kellner pro Stunde kostet.

          Das ist mir schon klar. Aber es gibt keine Verbindung zwischen den beiden zusammenhängenden Tabellen d und d1 auf der einen und d2 und d3 auf der anderen Seite ... insofern ist's kein Wunder, wenn bei der Abfrage viel zu viele nicht zusammensammengehörende Daten herauskommen.

          Ja, Joins hab ich nicht sooo im Griff und bei nem komplexeren Query lass ich die lieber weg, weil ich dann den Durchblick noch mehr verliere. Wäre aber für Vorschläge immer Dankbar!

          Lass es dir aus eigener Erfahrung gesagt sein: INSBESONDERE bei komplexeren Abfragen sind explizite JOINs weitaus einfacher zu durchschauen - hauptsächlich weil sofort klar wird, wie welche Tabellen zusammenhängen und sich in der WHERE-Einschränkung nur noch inhaltliche Dinge befinden.

          -----8<-----8<-----8<-----

          SELECT [...]
            FROM dbo.ZeitBuchung d
            JOIN dbo.Kellner     d1 ON d.kellnr = d1.Kellnr
            JOIN dbo.Bon         d2 ON /* ??? */
            JOIN dbo.Arti        d3 ON d2.artnr = d3.artnr
          WHERE d.FlOffen  = '-1'
             AND (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

          ----->8----->8----->8-----

          Spätestens wenn man deine Query so umschreibt, wird klar, was ich meine: es fehlt die Verknüpfung der Tabelle d2 mit dem Rest ...

          MfG,
          EKKi

          Hallo und danke für die schnelle Antwort!

          hmm.. ich verstehe immer noch nicht ganz? d2 ist ja mit d3 verbunden? In deinem Query ist es dann einfach bei der Zeile:

          JOIN dbo.Arti        d3 ON d2.artnr = d3.artnr

          gemacht. Oder wie kann ich das verstehen? Muss ich dann einfach nochmals ON d2.artnr = d3.artnr bei der Bon Tabelle anfügen? Wäre mir aber irgendwie nicht logisch.

          lg

          1. Mahlzeit,

            hmm.. ich verstehe immer noch nicht ganz? d2 ist ja mit d3 verbunden?

            Ja, d2 ist mit d3 verbunden. Und d ist mit d1 verbunden. Aber die beiden Tabellenpaare untereinander jeweils nicht. Also erstellt die Datenbank normalerweise ein Kreuzprodukt mit ALLEN Einträgen aus den verbundenen Tabellen d und d1 multipliziert mit ALLEN Einträgen aus den Tabellen d2 und d3 - ist es das, was du willst?

            Oder hängt eine der Tabellen d bzw. d1 irgendwie mit einer der Tabellen d2 oder d3 zusammen oder umgekehrt? Das würde deine Abfrage erheblich sinnvoller erscheinen lassen ... :-)

            MfG,
            EKKi

            --
            sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
            1. Mahlzeit,

              hmm.. ich verstehe immer noch nicht ganz? d2 ist ja mit d3 verbunden?

              Ja, d2 ist mit d3 verbunden. Und d ist mit d1 verbunden. Aber die beiden Tabellenpaare untereinander jeweils nicht. Also erstellt die Datenbank normalerweise ein Kreuzprodukt mit ALLEN Einträgen aus den verbundenen Tabellen d und d1 multipliziert mit ALLEN Einträgen aus den Tabellen d2 und d3 - ist es das, was du willst?

              Oder hängt eine der Tabellen d bzw. d1 irgendwie mit einer der Tabellen d2 oder d3 zusammen oder umgekehrt? Das würde deine Abfrage erheblich sinnvoller erscheinen lassen ... :-)

              MfG,
              EKKi

              Achso. :) Ich hab jetzt zwei Abfragen daraus erstellt und nun funktioniert es! Danke dir vieleviele Male!

              Hier noch die Abfragen:

              SELECT COUNT(d.FlOffen)        AS AnzKellner,
                     AVG(d1.brulohn)         AS DurchschnittBruLohn
                FROM dbo.ZeitBuchung d
                JOIN dbo.Kellner     d1 ON d.kellnr = d1.Kellnr
               WHERE d.FlOffen  = '-1'

              /**************************************************************/

              SELECT SUM(d2.PosWert)         AS SummeUmsatz,
                     SUM(d3.ekakt*d2.Menge)  AS SummeEK

              FROM dbo.Bon  d2
                JOIN dbo.Arti d3 ON d2.artnr = d3.artnr
               WHERE (DATEDIFF(hh, d2.BonDat, GETDATE()) <= 1)

              lg Immi