SQLER: SQL Abfrage: Artikel die innerhalb letzten JAhres bestellt wurden ausblenden

Hallo,

ich habe zwei Tabellen (Lagerartikel und Bestellartikel)

In beiden Tabellen stehen unsere Artikel drin. In der Bestallartikel Tabelle steht das Bestelldatum drin. Ich möchte nun aus der Lagerartikel Tabelle alle Datensätze aufgelistet haben, die aber die letzten 12 MOnate nicht mehr bestellt wurden.

Und nur diese Artikel. Die die aktuell innerhalb des Jahres bestellt wurden sollen nciht angezeigt werden. Ich stehe auf dem Schlauch und weis nicht wie.

Danke für Eure Hilfe

  1. Wo stehst du auf dem Schlauch? Zeig doch mal was du probiert hast. Wenn du Eigenleistung zeigt hebt das die Bereitwilligkeit der Leute dir zu helfen.

    select foo
    from lagerartikel
    where artikel_id in (
    	select artikel_id
    	from bestellartikel
    	where bestelldatum > now() - interval '1 year'
    )
    

    das geht aber schöner und schneller mit einem JOIN.

    1. ich hatte es so probiert:

      SELECT la.Lagerkennung, l.Name, la.Artikelnummer, la.IstMenge, la.Mindestbestand, la.Meldebestand, la.Auffuellbestand, la.BestandsErmittlungsArt
      FROM Lagerartikel la
      
      INNER JOIN Laeger l
      ON l.Lagerkennung = la.Lagerkennung
      
      WHERE la.Lagerkennung = '100' AND la.Artikelnummer IN (SELECT * FROM Bestellpositionen bp WHERE bp.AngelegtAm > GETDATE() -365)
      
      GROUP BY la.Lagerkennung, l.Name, la.Artikelnummer, la.IstMenge, la.Mindestbestand, la.Meldebestand, la.Auffuellbestand, la.BestandsErmittlungsArt
      

      Fehler: Nur ein einziger Ausdruck kann in der Auswahlliste angegeben werden, wenn die Unterabfrage nicht mit EXISTS eingeleitet wird

      1. ich glaube ich habs:

        SELECT la.Lagerkennung, l.Name, la.Artikelnummer, la.IstMenge, la.Mindestbestand, la.Meldebestand, la.Auffuellbestand, la.BestandsErmittlungsArt
        FROM Lagerartikel la
        
        INNER JOIN Laeger l
        ON l.Lagerkennung = la.Lagerkennung
        
        WHERE la.Lagerkennung = '221' AND la.Artikelnummer NOT IN (SELECT Artikelnummer FROM Bestellpositionen bp WHERE bp.AngelegtAm > GETDATE() -365)
        
        GROUP BY la.Lagerkennung, l.Name, la.Artikelnummer, la.IstMenge, la.Mindestbestand, la.Meldebestand, la.Auffuellbestand, la.BestandsErmittlungsArt
        

        stimmt das so?

        1. kommt das Richtige raus?

        2. Tach!

          stimmt das so?

          Die Abfrage ist am Ende ja noch komplexer als beschrieben. Macht nichts. Wenn das gewünschte Ergebnis rauskommt, dann stimmt das sicher so. Prüfungen mit Werten, die enthalten sein sollen und welche die nicht drin sein dürfen, können diese Frage beantworten. Als Außenstehender kann man da keine exakte Antwort geben, wennn nicht alle Dinge des Systems bekannt sind, besonders nicht, wenn das Tabellenlayout fehlt.

          Aber du kannst das selbst prüfen, indem du die einzelnen Teile prüfst, ob sie jeweils die geforderte Datenmenge liefern.

          Auch muss anhand der Mengen eine Plausibilität nachprüfbar sein. Die Query zu den Bestellungsartikeln liefert eine Anzahl Datensätze. Die Differenz zur Gesamtmenge in den Lagerartikeln und der endgültigen Ergebnismenge muss dieser Anzahl der Bestellungsartikel entsprechen.

          So wie du die Query aber aufgestellt hast, entspricht das jedoch dem, was ich auch manchen würde und vorgeschlagen habe.

          dedlfix.

          1. Dazu kann man sich ja auch leicht mal eben eine Testmenge mit 10..20 gut durchmischten Datensätzen erzeugen. Daran erkennt man ja schnell auf einen Blick, ob das gewünschte Ergebnis rauskommt.

    2. Hello,

      select foo
      from lagerartikel
      where artikel_id in (
      	select artikel_id
      	from bestellartikel
      	where bestelldatum > now() - interval '1 year'
      )
      

      Das ist aber nicht die Aufgabe gewesen.
      Jetzt hast Du alle Artikel gelistet aus Lagerartikel, die jemals bestellt wurden, aber nicht im gesperrten Zeitraum.

      Hier fehlt ein not for dem in und dann im Subselect alle Artikel selektieren, die im gesperrten Zeitraum lagen. Nennt sich Negationsabfrage.

      Liebe Grüße
      Tom S.

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
  2. Tach!

    ich habe zwei Tabellen (Lagerartikel und Bestellartikel)

    In beiden Tabellen stehen unsere Artikel drin. In der Bestallartikel Tabelle steht das Bestelldatum drin. Ich möchte nun aus der Lagerartikel Tabelle alle Datensätze aufgelistet haben, die aber die letzten 12 MOnate nicht mehr bestellt wurden.

    Und nur diese Artikel. Die die aktuell innerhalb des Jahres bestellt wurden sollen nciht angezeigt werden. Ich stehe auf dem Schlauch und weis nicht wie.

    Ein Verständnis von Mengen hilft bei solchen Aufgabenstellungen, sie zunächst einmal möglichst exakt formulieren zu können. Du hast also eine Menge Lagerartikel. Und du hast eine Menge Bestellungen, von denen du nur die der jüngsten 12 Monate berücksichtigen möchtest. Für diese beiden Mengen kannst du nun zunächst einmal einzelne Abfragen stellen, um zu prüfen, ob sie für sich genommen die richtigen Daten liefern. Bei den Lagerartikeln ist das in dem Fall nicht weiter sinnvoll, weil davon erstmal einfach alle berücksichtigt werden sollen. Die Bestelldaten hingegen brauchen eine WHERE-Klausel zum einschränken. Zudem benötigst du von diesen nur die Artikelnummer, so dass du zum Prüfen auf die richtige Datenmenge zwar * angeben kannst, aber dann die Feldliste auf die Artikelnummer beschränken kannst. Zudem brauchst du davon nur eindeutige Werte, also kannst du (musst aber nicht, wie wir gleich sehen werden) die Artikelnummern mit DISTINCT eindampfen. Das ergibt sinngemäß diese Query:

    SELECT artikelnr FROM Bestellungen WHERE in_den_vergangenen_12_Monaten
    

    Und nun möchtest du die Einträge aus den Lagerdaten, die nicht in der eben ermittelten Datenmenge der Bestellungen enthalten ist. Das ist dann ein einfaches Zusammenfügen der beiden Abfragen mittels NOT IN.

    SELECT was_du_brauchst FROM lagerartikel WHERE nr NOT IN (SELECT artikelnr FROM Bestellungen WHERE in_den_vergangenen_12_Monaten)
    

    Das erwähnte DISTINCT könnte so eingefügt werden

    … IN (SELECT DISTINCT artikelnr FROM Bestellungen …)

    aber es stört nicht, wenn die Werte mehrfach auftreten. Das Ergebnis des Ausdrucks änderet sich davon nicht.

    Alternativ ginge auch NOT EXISTS, wenn die Daten über mehr Kriterien als nur die nr verknüpft werden müssen.

    SELECT * FROM lagerartikel WHERE NOT EXISTS (SELECT * FROM bestellungen WHERE in_den_vergangenen_12_Monaten AND lagerartikel.nr = bestellungen.artikelnr AND lagerartikel.anderes_kriterium = bestellungen.anderes_kriterium )
    

    dedlfix.

  3. Hello,

    ich habe zwei Tabellen (Lagerartikel und Bestellartikel)

    In beiden Tabellen stehen unsere Artikel drin. In der Bestallartikel Tabelle steht das Bestelldatum drin. Ich möchte nun aus der Lagerartikel Tabelle alle Datensätze aufgelistet haben, die aber die letzten 12 MOnate nicht mehr bestellt wurden.

    Das widerspricht sich mit dem Betreff.

    Sollen nun alle Artikel angezeigt werden, außer denen, die in den letzten 12 Monaten bestellt wurden (diese also "ausgeblendet" werden => "Pennerliste"), oder sollen alle die Artikel angezeigt werden, die in den letzten 12 Monaten NICHT bestellt wurden?

    Das sind zwei verschiedene Mengen!

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
    1. Hallo,

      Das sind zwei verschiedene Mengen!

      da komm ich nicht mit, wo siehst du da einen Unterschied?

      Gruß
      Kalk

      1. Hallo Tabellenkalk,

        Das sind zwei verschiedene Mengen!

        da komm ich nicht mit, wo siehst du da einen Unterschied?

        Menge A: Alle Artikel
        Menge L: Artikel, die in den letzten 12 Monaten bestellt wurden.

        alle Artikel angezeigt werden, außer denen, die in den letzten 12 Monaten bestellt wurden

        A aber nicht L

        alle die Artikel angezeigt werden, die in den letzten 12 Monaten NICHT bestellt wurden

        A und nicht L

        Wenn L keine Teilmenge von A ist, sind die Mengen nicht gleich. Das könnte etwa sein, wenn Artikel bestellt wurden, die nicht in A vorkommen. Das sollte aber im konkreten Fall nicht vorkommen, weil "bestellt" sicher "Kaufvorgang abgeschlossen" bedeutet.

        Bis demnächst
        Matthias

        --
        Rosen sind rot.
        1. Hallo,

          A aber nicht L

          Gehört "aber" zu der Menge der logischen Ausdrücke?

          Wenn L keine Teilmenge von A ist

          Wie könnte das sein, wenn A für Alle steht?

          Gruß
          Kalk

          1. Hallo Tabellenkalk,

            Gehört "aber" zu der Menge der logischen Ausdrücke?

            Der Konnektor lautet \ auch Differenzmenge

            Wie könnte das sein, wenn A für Alle steht?

            schrieb ich ja, dass das nicht vorkommen wird. Das könnte aber sein, wenn ich beim Bäcker eine Flasche Pommes Frites bestelle.

            Mengendiagramm

            Wobei ich statt A und nicht L besser A oder nicht L hätte schreiben sollen. Umgangssprache in Logik zu übersetzen ist immer schwierig.

            Bis demnächst
            Matthias

            --
            Rosen sind rot.
            1. Hallo Tabellenkalk,

              Gehört "aber" zu der Menge der logischen Ausdrücke?

              Der Konnektor lautet \ auch Differenzmenge

              A aber nicht L ist das selbe wie A und nicht L, im Venn-Diagramm entspricht dies der Differenzmenge A\L.

              Mengendiagramm

              Wobei ich statt A und nicht L besser A oder nicht L hätte schreiben sollen. Umgangssprache in Logik zu übersetzen ist immer schwierig.

              A oder nicht L ist aber was anderes - das Venn-Diagramm dazu wäre dieses:

              1. Hello,

                nach Heisenberg hat es so ungefähr gestimmt ;-P

                Aber hier war es wohl mein Fehler. Die verkauften Artikel (Verkauf) sind laut Beschreibung des OP bezüglich ihrer Artikelnummern eine Untermenge des Warensortiments (Lager). Es gibt also keine Streckengeschäfte.

                Die Penner sind dann tatsächlich nur die Differenzmenge. Wie man eine solche bildet, wurde schon erwähnt und lässt sich sonst auch finden unter

                • Ausschlussabfrage
                • Differenzmenge
                • Negationsabfrage

                ![Mengendiagramm](/images/dc9679ac-1700-41f1-8946-1be7748a9fdb.png?size=medium "Bestimmung der "Pennermenge"")

                Liebe Grüße
                Tom S.

                --
                Es gibt nichts Gutes, außer man tut es!
                Das Leben selbst ist der Sinn.