1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Monatsliste mit left Join ?

Dieses Thema im Forum "Microsoft Access" wurde erstellt von Conan, 15 Mai 2016.

  1. Conan

    Conan Benutzer

    Hallo Community,

    nach einigem Kopfzerbrechen und erfolglosen Versuchen erbitte ich eure Hilfe:
    In einer Access Datenbank habe ich eine Tabelle in der verschiedene Monate des Jahres, als Datumsfeld verschieden oft vorkommen. Jedoch kommt nicht jeder Monat in der Tabelle vor.
    In einer Abfrage möchte nun aber eine Auflistung haben, in der in Spalte 1 alle Monate von Januar bis Dezember stehen und in Spalte 2 die Anzahl der Einträge für den jeweiligen Monat, wobei dann für den Monat, der in der Tabelle nicht auftaucht eine null erscheinen sollte.

    Wenn ich die Abfrage einfach in der Form aufbaue... :
    Select month(datum) as monat, count(month(datum)) as anzahl
    From tabplanung
    Group by month(datum)

    ... erhalte ich ja nur eine Liste für Monate in der Einträge stattgefunden haben.
    Wenn ich nun aber immer alle Monate aufgelistet haben möchte, auch wenn in dem Monat kein Eintrag stattgefunden hat, muss ich dann ne neue Monatstabelle mit allen Monaten erstellen und leftjoinen ?
    Wie baue ich die Abfrage auf ?
    Das ganze sollte dann so aussehen mit 1 für Januar und 12 für Dezember
    1 2
    2 0
    3 0
    4 5
    ...
    12 1

    Wenn z.B. für Februar und März kein Datumseintrag vorhanden war.
     
  2. akretschmer

    akretschmer Datenbank-Guru

    In PostgreSQL könntest Du Deine Join-Table direkt on-the-fly erstellen, der Join ginge dann so:

    Code:
    test=*# select * from conan ;
      datum   
    ------------
     2016-01-01
     2016-03-10
     2016-07-15
     2016-11-25
    (4 rows)
    
    test=*# select date_part('month', d), count(conan.*) from generate_series('2016-01-01', '2016-12-01','1 month'::interval) d left join conan on date_part('month', d) = date_part('month', conan.datum) group by 1;
     date_part | count
    -----------+-------
      1 |  1
      2 |  0
      3 |  1
      4 |  0
      5 |  0
      6 |  0
      7 |  1
      8 |  0
      9 |  0
      10 |  0
      11 |  1
      12 |  0
    (12 rows)
    
    Ich seh grad: man könnte das noch einfacher machen und einfach nur 1-12 generieren:

    Code:
    test=*# select d.d, count(conan.*) from generate_series(1,12) d left join conan on d.d = date_part('month', conan.datum) group by 1 order by 1;
     d  | count
    ----+-------
      1 |  1
      2 |  0
      3 |  1
      4 |  0
      5 |  0
      6 |  0
      7 |  1
      8 |  0
      9 |  0
     10 |  0
     11 |  1
     12 |  0
    (12 rows)
    
    Aufpassen mußt Du natürlich, wenn in Deiner Tabelle Daten von mehr als einem Jahr sind.
     
  3. Conan

    Conan Benutzer

    Danke, muss die Abfrage allerdings in der MS Access Datenbank erstellen. Da ist die Syntax doch etwas anders ?
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Ja, sicher. Die generate_series - Funktion gibt es da sicherlich nicht. Ich kenne dieses Spielzeug, ähm, Access, nicht.
     
  5. akretschmer

    akretschmer Datenbank-Guru

    hast du es nun? Sollte trivial sein.
     
  6. Conan

    Conan Benutzer

    Nein, mit PostgreSQL kann ich nichts anfangen.
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Hat nix mit PostgreSQL zu tun, Joins funktionieren gleich. Statt meiner generate-Funktion setzt Deine Tabelle ein.
     
  8. Conan

    Conan Benutzer

    Hier ein Bild meiner Tabelle:

    upload_2016-5-15_14-59-54.png

    Ich bin mittlerweile weiter und konnte mit der Abfrage...:

    SELECT tabmonate.name, count(rvzurueckam) as anzahl
    FROM tabmonate LEFT JOIN tabplanung a ON tabmonate.monatid = montH(a.rvzurueckam)
    WHERE (((Year([a].[rvzurueckam])) Is Null Or (Year([a].[rvzurueckam]))="2015"))
    group by tabmonate.name, tabmonate.monatid
    ORDER BY tabmonate.monatid

    folgenden View erstellen:
    upload_2016-5-15_15-5-50.png

    Nun würde ich gerne in Spalte 3 die Anzahl der Einträge für das Feld Datum anfügen. Wie muss ich die Abfrage anpassen ?
    Wenn ich einfach count(datum) as anzahl2 einfüge erhalte ich den View:

    upload_2016-5-15_15-11-6.png

    Dies ist aber fehlerhaft, da ich für März im Feld Datum 2 Einträge habe.
     
  9. akretschmer

    akretschmer Datenbank-Guru

    du mußt nun die Monatstabelle 2 mal joinen, nun mit der anderen Spalte. Verwende Aliase, um zwischen den zwei gejointen Tabellen unterscheiden zu können.
     
  10. Conan

    Conan Benutzer

    Bekomme ungruppiert mit der Abfrage:

    SELECT *
    FROM
    (tabmonate LEFT JOIN tabplanung AS a ON tabmonate.monatid = month(a.rvzurueckam))
    LEFT JOIN tabplanung AS b ON tabmonate.MonatID = month(b.Datum)
    WHERE (Year(a.rvzurueckam) Is Null Or Year(a.rvzurueckam)="2015")
    and (year(b.datum) is null or year(b.datum) ="2015")
    ORDER BY tabmonate.monatid;

    den View:
    upload_2016-5-15_15-37-11.png

    Jetzt müssten allerdings für März die Spalten aus Tabelle B und für Juni die Spalten aus A aggregiert werden, damit das Ergebnis korrekt angezeigt wird. Hier komme ich nicht weiter..
     
  11. akretschmer

    akretschmer Datenbank-Guru

    Code:
    test=*# select * from conan ;
      datum  |  datum2   
    ------------+------------
     2016-01-01 |
     2016-03-10 |
     2016-07-15 |
     2016-11-25 |
      | 2016-02-01
      | 2016-04-01
      | 2016-07-01
      | 2016-11-01
      | 2016-12-01
    (9 rows)
    
    test=*# select s.s, count(c1.*), count(c2.*) from (select s from generate_series(1,12)s)s left join conan c1 on s.s = date_part('month', c1.datum) left join conan c2 on s.s=date_part('month', c2.datum2) group by 1 order by 1;
     s  | count | count
    ----+-------+-------
      1 |  1 |  0
      2 |  0 |  1
      3 |  1 |  0
      4 |  0 |  1
      5 |  0 |  0
      6 |  0 |  0
      7 |  1 |  1
      8 |  0 |  0
      9 |  0 |  0
     10 |  0 |  0
     11 |  1 |  1
     12 |  0 |  1
    (12 rows)
    
    Du bekommst die Idee?
     
  12. Conan

    Conan Benutzer

    Ich verstehe deinen Vorschlag als:

    SELECT s.monatid, Count(c1.rvzurueckam) AS anzahl1, Count(c2.datum) AS anzahl2
    FROM
    ((select monatid from tabmonate) AS s
    LEFT JOIN tabplanung AS c1 ON s.monatid = month(c1.RVzurueckAm))
    LEFT JOIN tabplanung AS c2 ON s.monatid = month(c2.Datum)
    WHERE (((Year([c1].[rvzurueckam])) Is Null Or (Year([c1].[rvzurueckam]))="2015") AND ((Year([c2].[datum])) Is Null Or (Year([c2].[datum]))="2015"))
    GROUP BY s.monatid
    ORDER BY s.monatid;

    View sieht dann so aus:
    Dies ist nicht korrekt...


    upload_2016-5-15_16-46-12.png
     
  13. akretschmer

    akretschmer Datenbank-Guru

    so auf die schnelle: dein JOIN ist falsch.
     
  14. Conan

    Conan Benutzer

    Dann korrigier mich bitte in meinem Beispiel
     
  15. akretschmer

    akretschmer Datenbank-Guru

    du hast da wild (und wohl zum Teil falsch) Klammern gesetzt, ich denke, das ist die Ursache. Versuch zu verstehen, was ich Dir gezeigt habe.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden