Kurt: sql Abfrage

Moin,

ich habe eine Tabelle X mit den Feldern Kundennummer und Datum

Nun möchte ich alle Kunden mit einem Datum innerhalb 2020 herausfiltern, die zuvor noch nicht in der Tabelle vorkamen.

Deshalb frage ich wie folgt

SELECT DISTINCT Kundennummer
FROM tableX
WHERE Datum >= '2020-01-01' AND
Kundennummer NOT IN
( SELECT 
Kundennummer 
FROM tableX
WHERE
Datum <= '2020-01-01'
)

Mir kommt das Ergebnis trotzdem recht hoch vor, deshalb frage ich mal nach, ob meine Query so passt oder ob ich etwas übersehen habe?

Kurt

  1. Hallo Kurt,

    nein, scheint mir richtig. Aber wenn Du glaubst, dass dein Ergebnis falsch ist, mach Stichproben. Wenn Kundennummern drin sind, die Datümer vor 2020 haben, haben wir beide einen Denkfehler.

    Auf jeden Fall scheint mir dein Statement ineffizient, weil Du für jede Row in tableX prüfst, ob es zur Kundennummer keinen Eintrag vor 2020 gibt. Das sind eine Menge Subselects.

    Ich würde dazu das folgende SQL benutzen. Du könntest es zur Kontrolle verwenden.

    SELECT   kundennummer, MIN(datum)
    FROM     tableX
    GROUP BY kundennummer
    HAVING   MIN(datum) >= '2020-01-01'
    

    Ob man MIN(datum) in die SELECT Liste setzen muss, weiß ich nicht aus dem Kopf, das müsste ich ausprobieren, es mag auch DBMS spezifisch sein.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      nein, scheint mir richtig. Aber wenn Du glaubst, dass dein Ergebnis falsch ist, mach Stichproben. Wenn Kundennummern drin sind, die Datümer vor 2020 haben, haben wir beide einen Denkfehler.

      Danke für Deine Antwort. Und leider war meine Query nicht ganz richtig ;)

      Herausgefunden habe ich es dann mit deiner Query, die mir viel realistischer im Ergebnis erschien.

      Auf jeden Fall scheint mir dein Statement ineffizient, weil Du für jede Row in tableX prüfst, ob es zur Kundennummer keinen Eintrag vor 2020 gibt. Das sind eine Menge Subselects.

      Das wär enicht ganz si dramatisch, weil es nur um < 30.000 Einträge geht, da ist das verkraftbar. Aber recht hast Du natürlich.

      Jedenfalls greift das DISTINCT bei meiner Query nicht, somit ist das Ergebnis deutlich zu hoch und genau das hatte ich schon im Gefühl. Wenn ich aber nach Kundennummer gruppiere, kommen unsere beiden Queries auf exact dasselbe Ergebnis und ein Ergebnis dieser Größenordnung hatte ich auch bauchgefühlmäßig erwartet.

      Danke also für die Prüfquery, die mir bei der Fehlersuche meiner Query geholfen hat.

      Frage an die Spezialisten: Warum greift das DISTINCT meiner Query nicht?

      Kurt

      1. Hallo Kurt,

        Frage an die Spezialisten: Warum greift das DISTINCT meiner Query nicht?

        Bin ich, aber ich zucke mit den Schultern. Ich habe eine ähnliche Table mit ID-Nummern und Datum, und wenn ich deine Query darauf absetze, kommt das gleiche heraus wie bei meiner GROUP BY Query.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Hallo Rolf,

          Bin ich, aber ich zucke mit den Schultern. Ich habe eine ähnliche Table mit ID-Nummern und Datum, und wenn ich deine Query darauf absetze, kommt das gleiche heraus wie bei meiner GROUP BY Query.

          Rolf

          Sorry, Du hast Recht und nicht alle Informationen. In diesem verkürztem Beispiel benötigt es das Group by nicht. In meiner Produktivquery hängt noch ein JOIN über die Kundennummer auf die Kundentabelle mit drin, der dafür verantwortlich ist.

          Aber auch hier weiß ich nicht, warum der JOIN das DISTINCT außer Kraft setzt.

          Kurt

          1. Hallo Kurt,

            das kann ich Dir nur sagen, wenn ich die Produktivquery sehe.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Kurt,

              das kann ich Dir nur sagen, wenn ich die Produktivquery sehe.

              Rolf

              Hi Rolf,

              hier gings nur um ein Arbeitsinstrument, das nach einmaliger Benutzung eine Tabelle erzeugt, die relevant ist. Nachdem ich diese Tabelle hatte, habe ich die Arbeitsquery in die digitalen ewigen Jagdgründe gesendet... 😉

              Du hast mir jedenfalls mit Deiner Vergleichsquery klasse geholfen und so konnte ich meine Query korrigieren. Danke.

              Kurt

  2. Dann lösen wir das mal logisch auf:

    Der Subselect liefert eine Liste von Kundennummern, zu denen ein Datum kleiner oder gleich dem 2020-01-01 gehört.

    1. Der Select wählt dann alle Kundennummern, zu denen ein Datum größer oder gleich dem 2020-01-01 gehört und welche nicht kleiner oder gleich dem 2020-01-01 sind.

    2. In der Konsequenz bekommst Du also alle Kundennummern, die ein Datum ab dem 2020-01-01 haben, abzüglich derer, die genau das Datum vom 2020-01-01 tragen.

    Also alle Kunden mit einem Datum ab dem 2020-01-02.

    Das ist nicht, was Du willst, aber da sich mir der logische Sinn nicht erschließt, kann ich nicht mehr beitragen als das. Ich vermute, es gibt tatsächlich zwei Datumsangaben: Ein Kaufdatum und ein Datum, an welchem die Kundennummer angelegt wurde...

    1. Hallo Raketenlogistiker,

      stimmt, die Query liefert die Kunden, die ab dem 2.1.2020 hinzugekommen sind, nicht die, die ab dem 1.1.2020 hinzugekommen sind. Im Subselect hätte ein "<" stehen müssen.

      Aber das erklärt nicht, warum der DISTINCT nicht zu greifen scheint. Der sollte doppelte Ergebnisse ausschließen und laut OP tut er das nicht. Ich habe es in einer meiner eigenen DBs nachgestellt - bei mir funktioniert es, mit MySQL.

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Ich habe es in einer meiner eigenen DBs nachgestellt - bei mir funktioniert es, mit MySQL.

        In SQLite3 auch.

        Aber: Vielleicht hat er ja noch eine Spalte mehr abgefragt als uns gezeigt:

        ~~SQL SELECT DISTINCT Kundennummer FROM Kunden WHERE Datum >= '2020-01-01' AND Kundennummer NOT IN ( SELECT Kundennummer FROM Kunden WHERE Datum <= '2020-01-01')

        
        (2 Zeilen)
        
        vers.
        
        
        ~~~sql
        SELECT DISTINCT Kundennummer, Datum
        FROM Kunden
        WHERE Datum >= '2020-01-01' AND
        Kundennummer NOT IN
        ( SELECT 
        Kundennummer 
        FROM Kunden
        WHERE
        Datum <= '2020-01-01')
        

        (3 Zeilen: wenn Datum unterschiedlich, Kundennummern kommen mehrfach vor.)

        1. Ich habe es in einer meiner eigenen DBs nachgestellt - bei mir funktioniert es, mit MySQL.

          In SQLite3 auch.

          Aber: Vielleicht hat er ja noch eine Spalte mehr abgefragt als uns gezeigt:

          SELECT DISTINCT Kundennummer
          FROM Kunden
          WHERE Datum >= '2020-01-01' AND
          Kundennummer NOT IN
          ( SELECT 
          Kundennummer 
          FROM Kunden
          WHERE
          Datum <= '2020-01-01')
          

          (2 Zeilen)

          vers.

          SELECT DISTINCT Kundennummer, Datum
          FROM Kunden
          WHERE Datum >= '2020-01-01' AND
          Kundennummer NOT IN
          ( SELECT 
          Kundennummer 
          FROM Kunden
          WHERE
          Datum <= '2020-01-01')
          

          (3 Zeilen: wenn Datum unterschiedlich, Kundennummern kommen mehrfach vor.)

          1. Hallo Raketenlogistiker,

            also, bei SELECT DISTINCT kundennummer, datum zu erwarten, dass die Kundennummern eindeutig werden, das wäre aber schon ganz schön ***meep***.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. das wäre aber schon ganz schön meep.

              Die meisten Fehler geschehen auf OSI-Level 8 und 9 …

    2. Also alle Kunden mit einem Datum ab dem 2020-01-02.

      Hast Du auch wieder recht, danke. 😉