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

SQL Statement oder andere Struktur

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von gnetics, 3 Mai 2013.

  1. gnetics

    gnetics Neuer Benutzer

    Hallo Zusammen,

    ich habe einwenig Erfahrung in mySql stoße aber nun an meine Grenzen und hoffe auf Hilfe.

    Ich habe zwei Tabellen.

    Tabelle 1:

    ID Start Stop1 Stop2 Stop 3 Stopn Ziel
    1 47906 47809 52066
    2 52066 47809 47906
    3 47475 47809 47906 47105 52066
    4 52066 47105 47906 47809 47475

    Dabei handelt es sich um PLZ die in einer bestimmten Route abgefahren werden.

    Beginn in 47906 über 47809 und Ende 52066

    In einer zweiten Tabelle stehen nur ID PLZ und Name der Stadt.

    ID PLZ Name
    1 47906 Kempen
    2 47809 Krefeld

    Da immer nur erreicht werden kann was rechts in einer Zeile steht brauch ich dafür eine Abfrage bin aber überfragt.

    Sprich übergebe ich 47906 darf für

    Zeile 1 nur: 47809, 52066
    Zeile 2 nur: -
    Zeile 3 nur: 47105, 52066
    Zeile 4 nur: 47809, 47475

    als Ergebnis rauskommen.

    Wie mache ich das, oder sollte ich die Tabellen ganz anders aufbauen?

    Wäre super, wenn mir jemand helfen könnte.

    Gruß
    Björn
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ja. Ganz anders. Dein Ansatz skaliert nicht. Du hast Stop1 bis Stop3 und StopN. Hier merkst ja vielleicht schon selber, daß Du N Spalten brauchst, und N kann praktisch recht groß werden. Eigentlich willst Du es anders speichern, und zwar so, daß man den Vorgänger bekommt. Zum Beispiel so:

    Code:
    test=# create table wege (id int primary key, plz text, vorher int references wege);
    NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "wege_pkey" for table "wege"
    CREATE TABLE
    
    Da kannst dann Wege zwischen den einzelnen PLZs reinwerfen soviel Du willst. Abfragen kann man das dann über rekursive Abfragen. Das war die gute Nachricht für Dich. Die schlechte: MySQL kann das nicht.

    Ich könnte Dir das ganz elegant als rekursive Abfrage in PostgreSQL zeigen, falls Du das sehen willst, sag Bescheid. Für MySQL bleibt diese Lösung: http://www.klempert.de/nested_sets/
     
  3. gnetics

    gnetics Neuer Benutzer

    Vielen Dank für die Antwort.

    Meine PostgreSQL Erfahrung ist zwar gleich null, aber ich bin gewillt zu lernen. Dann stelle ich wohl mal um und würde mich freuen, wenn du mir zeigst wie ich das elegant mit PostgreSQL löse.
     
  4. gnetics

    gnetics Neuer Benutzer

    Wichtig wäre vielleicht noch. Ich brauche nicht immer den Vorgänger. Mal ist gefragt 47906 ist das Ziel von welcher PLZ komme ich dahin und in einer anderen Abfrage ist 47906 der Start und brauche das Ergebnis was ich erreichen kann.
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Also, Du hast:

    Code:
    test=*# select * from wege;
     id |  plz  | vorher
    ----+-------+--------
      1 | 47906 |
      2 | 47809 |      1
      3 | 52066 |      2
      4 | 52066 |
      5 | 47809 |      4
      6 | 47906 |      5
      7 | 47475 |
      8 | 47809 |      7
      9 | 47906 |      8
     10 | 47105 |      9
     11 | 52066 |     10
     12 | 52066 |
     13 | 47105 |     12
     14 | 47906 |     13
     15 | 47809 |     14
     16 | 47475 |     15
    (16 rows)
    
    Das sind exakt Deine Daten (wennn ich mich nicht vertippt habe), nur die Tabelle ist anders definiert. Wie schon in meiner ersten Antwort gezeigt.

    Nun etwas Magie:

    Code:
    test=*# with recursive r as
    test-#   (select p.*, 1 as level, row_number() over () as weg_nr from wege p where plz='47906'
    test(#   union all
    test(#   select p.*, r.level+1, r.weg_nr from wege p join r on r.id=p.vorher
    test(#   )
    test-# select * from r order by weg_nr, level;
     id |  plz  | vorher | level | weg_nr
    ----+-------+--------+-------+--------
      1 | 47906 |        |     1 |      1
      2 | 47809 |      1 |     2 |      1
      3 | 52066 |      2 |     3 |      1
      6 | 47906 |      5 |     1 |      2
      9 | 47906 |      8 |     1 |      3
     10 | 47105 |      9 |     2 |      3
     11 | 52066 |     10 |     3 |      3
     14 | 47906 |     13 |     1 |      4
     15 | 47809 |     14 |     2 |      4
     16 | 47475 |     15 |     3 |      4
    (10 rows)
    
    Die Spalte weg_nr sind die unterschiedlichen Wege, level die n. Station auf dem Weg. Die Spalte vorher ist hier nun überflüssig, egal.

    Das mag erst einmal ungewohnt aussehen, aber via Google und 'rekursive abfragen postgresql' bekommst jede Menge Anleitung dafür.
     
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