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

Abfrage über Tabellen deren Name in einer Tabelle stehen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von enseth439, 1 Oktober 2013.

  1. enseth439

    enseth439 Aktiver Benutzer

    Hallo, meine SQL Kenntnisse reichen leider nicht aus das gesuchte in einer einzelnen Abfrage zu erledigen. Problem ist hier, dass die Tabellennamen in einer Tabelle stehen.

    Die Tabellen sehen in etwa so aus:
    Code:
    main: id, tabelle-x, id-x, plz, geloescht
    x1: id, endedatum, geloescht
    x2: id, endedatum, geloescht
    Gesucht sind jetzt jeweils alle Postleitzahlen sortiert nach nicht gelöscht und deren Endedatum, ohne doppelte PLZ. Endedatum kann auch mal leer sein, dann ist geloescht = 0 sonst -1. Die id-x ist nicht eindeutig, also jede Tabelle-x kann z.B. die ID 120 haben.

    Ist das überhaupt möglich in einer Abfrage?
     
    Zuletzt bearbeitet: 4 Oktober 2013
  2. akretschmer

    akretschmer Datenbank-Guru

    Das klingt etwas wirr. Kannst Du das mal an einem Beispiel zeigen?

    Wenn der Tabellennamen in einer Spalte steht wird es darauf hinauslaufen, dynamisches SQL zu generieren und dieses via EXECUTE auszuführen. Für PG ist das kein Ding (für mich), mit M$SQL kenn ich mich nicht aus, aber der @ukulele kommt bestimmt auch gleich ;-)
     
  3. enseth439

    enseth439 Aktiver Benutzer

    Hier ein Beispiel
    Code:
    main:
    id, tabelle-x, id-x, plz, geloescht
    100, x1, 150, 21029, -1
    101, x2, 200, 21029, 0
    ...
    
    x1:
    id, endedatum, geloescht
    150, 01.10.2013, -1
    ...
    
    x2:
    id, endedatum, geloescht
    200, <null>, 0
    ...
    
    Soll liefern:
    id, tabelle-x, id-x, plz, geloescht,endedatum
    101, x2, 200, 21029, 0, <null>
    ...
    Danke fürs draufschauen...
     
    Zuletzt bearbeitet: 4 Oktober 2013
  4. ukulele

    ukulele Datenbank-Guru

    Also EXECUTE ist kein Ding sollte sich nicht von PG unterscheiden und das ist hier auch notwendig, da stimme ich zu.
     
  5. enseth439

    enseth439 Aktiver Benutzer

    Ok, dann weiß ich schon mal wohin ich schauen muss.
    Danke.
     
  6. ukulele

    ukulele Datenbank-Guru

    Ok wenn ich das Problem mal genauer betrachte (sry hatte neulich nicht die Ruhe) dann ist dynamisches SQL sehr mühselig, man müsste schon mit einer Schleife einen Select zusammen kleistern. Sind es wirklich viele Tabellen oder hält sich die Anzahl in Grenzen? Ansonsten könnte man auch mit einer CASE Schleife und Subselects oder UNION arbeiten.
     
  7. ukulele

    ukulele Datenbank-Guru

    Code:
    SELECT    m.id,
            m.tabelle-x,
            m.id-x,
            m.plz,
            m.geloescht,
            x1.enddatum AS enddatum
    FROM    main m
    LEFT JOIN x1 ON m.id-x = x1.id
    WHERE    m.tabelle-x = 'x1'
    UNION ALL
    SELECT    m.id,
            m.tabelle-x,
            m.id-x,
            m.plz,
            m.geloescht,
            x2.enddatum AS enddatum
    FROM    main m
    LEFT JOIN x2 ON m.id-x = x2.id
    WHERE    m.tabelle-x = 'x2'
     
  8. enseth439

    enseth439 Aktiver Benutzer

    Grob sind das 10 Tabellen. Alle paar Jahre kommt mal eine dazu. Dann heißt es wohl die Abfrage anpassen. Mit UNION sieht das sehr übersichtlich aus, würde sich dann aber ganz schön oft wiederholen :). Geht das mit CASE vielleicht kompakter? Brauche ich dann ein CASE im JOIN und im WHERE Statement?

    Ein Problem ist noch die Sortierung. Wenn es einen aktiven Eintrag gibt, sollen weitere gelöschte nicht als Ergebnis ausgegeben werden, ansonsten nur der zuletzt gelöschte. Mit FIRST und GROUP BY sollte das gehen.
    Code:
    SELECT mit FIRST(...) außer PLZ
    ...
    LEFT JOIN ON
        m.tabelle-x = CASE....
    WHERE ...
        m.tabelle-x = CASE....
    GROUP BY
      (m.plz)
    ORDER BY
      First(m.plz),
      First(m.geloescht) DESC
    Ja, enddatum fehlt noch. Das kommt bestimmt aus der Schleife mit dem Subselect.
    Wie jetzt nochmal Schleife und Subselect?
    :( Öh, schönes Ding.
     
    Zuletzt bearbeitet: 8 Oktober 2013
  9. akretschmer

    akretschmer Datenbank-Guru

    Das klingt mir nach Partitionierung als Lösung.
     
  10. ukulele

    ukulele Datenbank-Guru

    Man kann alles dynamisch zusammen kleistern aber ich denke UNION ist schlichter und wenn man alle mit UNION verkettete Selects noch als Subselect nimmt kann man auch sortieren.
    Code:
    SELECT    asdf
    FROM (
    SELECT    asdf
    FROM    qwert1
    UNION ALL
    SELECT    asdf
    FROM    qwert2
    ) tabelle
    ORDER BY asdf
    Ich frage mich aber auch warum die Daten erst in verschiedene Tabellen zerlegt werden um dann wieder zusammengeklebt zu werden :)
     
  11. enseth439

    enseth439 Aktiver Benutzer

    Das Datenbankkonzept ist fragwürdig. Gedacht ist es wohl so, dass man abfragt in welcher Tabelle man schauen soll und dann dort noch mal eine Abfrage nach dem Ergebnis stellt. Es wird dann immer nur eine weitere Tabelle benötigt. Ich bin jetzt der Held, der die Tabellen ausnahmsweise zusammenkleben will, um die letzt gültigen Einträge über alle Tabellen zu finden. :eek:

    Partitionierung: Das ist sicher eine tolle Sache, aber da die Datefunktion hinzukriegen ist über meinem Können.

    Ich kriege das nicht mal mit CASE hin und werde das jetzt mal mit UNION auf zwei Tabellen probieren. So wie ukulele das vorgeschlagen hat. Wenn das geht, dann kommen die anderen noch hinzu bzw. lasse ich den SQL String mittels einer Programmschleife zusammensetzen. Dann wäre ich schon glücklich.
     
    Zuletzt bearbeitet: 8 Oktober 2013
  12. enseth439

    enseth439 Aktiver Benutzer

    Das sah eigentlich ganz gut aus, aber FIRST und LAST gibt es nicht in MSSQL als Aggregatfunktion (das hatte in ACCESS zusammengebaut). MIN und MAX sind kein Ersatz und verhalten sich anders. Also muss die Sortierung noch mal angepasst werden...
     
    Zuletzt bearbeitet: 8 Oktober 2013
  13. ukulele

    ukulele Datenbank-Guru

    Ich kenne jetzt FIRST und LAST nicht aber hört sich an wie
    Code:
    SELECT TOP 1 spalte FROM tabelle ORDER BY spalte
    und
    SELECT TOP 1 spalte FROM tabelle ORDER BY spalte DESC
    Zugegeben TOP ist sehr gewöhnungsbedürftig. Manchmal wünsche ich mir auch LIMIT in MSSQL.
     
  14. enseth439

    enseth439 Aktiver Benutzer

    TOP1 liefert den ersten Datensatz. In UNION dann jeweils einen je Tabelle. Dann könnte man zwar gruppieren, das würde aber nicht einen Datensatz je Gruppe liefern sondern je Tabelle.

    "Top 1 row of each group" heißt das Problem. Die Lösungen lauten z.B. so:

    ROW_NUMBER() OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC) AS rn
    WHERE rn =1

    PARTITION BY, wenn das akretschmer mit Partitionierung gemeint hat, ziehe ich meinen Hut :D.

    Es gibt auch noch weitere Möglichkeiten über JOIN. Naja, das probiere ich gerade aus. Es ist aber nicht so einfach für mich.
     
  15. akretschmer

    akretschmer Datenbank-Guru

    Nein. Ich habe gequotet, worauf ich mich bezog. Jedes jahr 'ne neue Tabelle und das Statement anpassen...
     
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