Ankündigung

Einklappen
Keine Ankündigung bisher.

Ein Eintrag aus Tabelle 1 mit 2 Einträgen aus Tabelle 2 - wenn vorhanden

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Ein Eintrag aus Tabelle 1 mit 2 Einträgen aus Tabelle 2 - wenn vorhanden

    Guten Abend,

    ich erstelle gerade eine DB für alle Adressen der Schweiz. Dazu habe ich eine CSV der Schweizerischen Post erhalten. Da für den Usecase nur ca 10% der enthaltenen Daten verwendet werden, bin ich daran die Datenbank zurechtzustutzen. Die grösste Schwierigkeit - die Schweiz hat für einige Ortsnamen und Strassennamen verschiedene Sprachen. In der Haupttabelle ist jeweils die für den Ort gesprochene Sprache hinterlegt. Die alternativen Sprachen sind in einer zweiten Tabelle enthalten.

    Ich habe nun eine case when Abfrage erstellt in Kombination mit LEFT JOIN um alle Sprache in einer Row auszugeben. Dabei ergeben sich zwei Probleme:
    Problem 1: Es wird immer Deutsch & Französisch oder Französisch und Italienisch eingetragen. Die jeweils fehlende Sprache wird (wegen JOIN) um eine weitere Zeile beigefügt.
    Problem 2: Ich weiss nicht genau wie ich zwei Zeilen aus Tabelle 2 in einem Rutsch in eine Row bekomme.

    Was habe ich versucht: Group By. Das wirft jedoch immer eine Fehlermeldung:
    Code:
    [42000][1055] Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'adressen.NEW_PLZ2.SPRACHCODE' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
    (Auch wenn ich den STRICT MODE deaktiviere - erhalte ich nicht das gewünschte Ergebniss)
    Nach google und SO habe ich die Group By um alle enthaltenen Feldern erweitert. Dann lässt sich der Query zwar ausführen, aber enthält trotzdem nicht die gewünschte Ergebnisse ( es ist dann nur noch die Französische Variante vorhanden und viele Ergebnisse Fehlen.)

    Folgend der Query den ich verwende:

    Code:
     SELECT
    NEW_PLZ1.ONRP,
           case
               when NEW_PLZ1.SPRACHCODE = '1' then NEW_PLZ1.ORTBEZ18
               when NEW_PLZ2.SPRACHCODE = '1' then NEW_PLZ2.ORTBEZ18
           end as 'DE_ORTNAME',
            case
                when NEW_PLZ1.SPRACHCODE = '2' then NEW_PLZ1.ORTBEZ18
                when NEW_PLZ2.SPRACHCODE = '2' then NEW_PLZ2.ORTBEZ18
            end as 'FR_ORTNAME',
            case
                when NEW_PLZ1.SPRACHCODE = '3' then NEW_PLZ1.ORTBEZ18
                when NEW_PLZ2.SPRACHCODE = '3' then NEW_PLZ2.ORTBEZ18
            end as 'IT_ORTNAME'
    FROM
        NEW_PLZ1 LEFT JOIN NEW_PLZ2 ON NEW_PLZ1.ONRP = NEW_PLZ2.ONRP
    group by NEW_PLZ1.ONRP;
    Meine Frage nun: Wie kann ich aus Tabelle_1 eine Zeile ausgeben und diese Zeile mit 2 Tabelleneinträgen von Tabelle_2 ergänzen? Es ist egal, wie langsam die Abfrage ist, da diese nur einmal ausgeführt wird um die Daten in eine neue Tabelle umzuschreiben. Oder ist mein Weg mit Group By die richtige Richtung und mache ich nur was falsch?

    Über Hilfe freue ich mich.

    Grüsse SoDaho

  • #2
    Moin. Ich wohne zwar gar nicht so weit weg von der schweizer Grenze, aber ich habe keine Ahnung, wie das mit den Straßennamen in der Schweiz funktioniert.
    Entsprechend bekomme ich da jetzt auch einen Teil nicht richtig zusammen: Gibt es pro Stadt und Straße zwei oder mehr Namen, oder gibt es im Prinzip nur einen Straßennamen, der dann aber in einer von drei Sprachen notiert sein kann?
    Romanische Straßennamen gibt es nicht?
    Wenn es pro Straße (in einer Stadt) nur einen Namen geben kann, dann ist die Sprache zunächst mal nur ein unwesentliches Detail, oder? Wenn es mehrere Namen geben kann: Was genau willst du am Ende für Daten bekommen?

    Zitat von sodaho Beitrag anzeigen
    Meine Frage nun: Wie kann ich aus Tabelle_1 eine Zeile ausgeben und diese Zeile mit 2 Tabelleneinträgen von Tabelle_2 ergänzen? Es ist egal, wie langsam die Abfrage ist, da diese nur einmal ausgeführt wird um die Daten in eine neue Tabelle umzuschreiben. Oder ist mein Weg mit Group By die richtige Richtung und mache ich nur was falsch?
    Pivot. Z.B. so: https://www.db-fiddle.com/f/jZooU55zdKVL3KcPKt6EvS/0

    Kommentar


    • #3
      Hey rkr
      Das mit den Ortsnamen und Strassen funktioniert so. Zug z.B. ist im Deutschsprachigen Teil der Schweiz. Dort sind alle Strassennamen und Ortsnamen auf Deutsch. Für einige gibt es jedoch das Italienische oder Französische Pendant. (Kann - nicht muss)
      Das sieht dann für Zug so aus: Zug (DE) Zoug (FR) Zugo (IT) Für Yvonand existiert z.B. nur der Französische Name.

      Selbiges gilt auch für Strassennamen. Für die Post spielt es theoretisch keine Rolle, welche Sprache benutzt wird (solange nicht gemixt in der selben Adresse), gibt aber im offiziellen Verzeichniss immer die entsprechend gesprochene Sprache als Standart. Also ist in der Haupttabelle Zug als DE geführt und Genf als Genève. Jetzt gibt es Kunden, die geben ihre Adresse mal in Franz. mal in Deutsch an. Im Geschäft haben sich so einige inkorrekt gespeicherten Adressen angesammelt. Um das zu verhidnern, gleichen wir zukünftig mit den offiziellen Daten ab.

      Hab dieselbe Frage gestern auch noch auf StackOverflow gestellt: https://stackoverflow.com/questions/...ows-in-one-row

      Die lösung ist so einfach wie simpel:
      Die Case when in die aggregate function SUM() packen - dann funktioniert Group By und ich erhalte eine Zeile pro Ortschaft mit den Namen in DE_ORT | FR_ORT | IT_ORT. https://dev.mysql.com/doc/refman/8.0...functions.html

      Die schwierigkeit die mir beim Fragestellen auflag, es geht um denormalization - da landet man oft auf der Antwort: Macht man nicht Und mir gingen irgendwie die Ideen aus, nach was und wie suchen, und war 0 kreativ dabei.

      Mein Query sieht nun so aus:

      Code:
       SELECT
           NEW_PLZ1.ONRP,
           MAX(case when NEW_PLZ1.SPRACHCODE = '1' then NEW_PLZ1.ORTBEZ18 when NEW_PLZ2.SPRACHCODE = '1' then NEW_PLZ2.ORTBEZ18 end) as 'DE_CITY',
           MAX(case when NEW_PLZ1.SPRACHCODE = '2' then NEW_PLZ1.ORTBEZ18 when NEW_PLZ2.SPRACHCODE = '2' then NEW_PLZ2.ORTBEZ18 end) as 'FR_CITY',
           MAX(case when NEW_PLZ1.SPRACHCODE = '3' then NEW_PLZ1.ORTBEZ18 when NEW_PLZ2.SPRACHCODE = '3' then NEW_PLZ2.ORTBEZ18 end) as 'IT_CITY'
       FROM
           NEW_PLZ1
       LEFT JOIN NEW_PLZ2 ON NEW_PLZ1.ONRP = NEW_PLZ2.ONRP
       GROUP BY NEW_PLZ1.ONRP;

      Kommentar


      • #4
        Zitat von sodaho Beitrag anzeigen
        Hey rkr
        Die schwierigkeit die mir beim Fragestellen auflag, es geht um denormalization - da landet man oft auf der Antwort: Macht man nicht Und mir gingen irgendwie die Ideen aus, nach was und wie suchen, und war 0 kreativ dabei.
        Um ehrlich zu sein haben die ja auch recht. Ich nehme an, deine SQL Fähigkeiten reichen einfach nicht aus um die original Datenbank ordentlich abzufragen. Daher bastelst du dir jetzt irgendeine einfacherer Variante mit der du klar kommst. On das der richtige Weg ist wage ich irgendwie zu bezweifeln.

        Pre-Coffee-Posts sind mit Vorsicht zu geniessen!

        Kommentar


        • #5
          Zitat von sodaho Beitrag anzeigen
          Die schwierigkeit die mir beim Fragestellen auflag, es geht um denormalization - da landet man oft auf der Antwort: Macht man nicht Und mir gingen irgendwie die Ideen aus, nach was und wie suchen, und war 0 kreativ dabei.
          Ich habe ja in meinem Beispiel eine normalisierte Variante gezeigt. Die ID steht dabei für die Straße. Die Tabelle an sich für die Sprachen, in denen eine Straße verfügbar sein kann. Die Abfrage kann man auch anders schreiben. Aber im Prinzip ist der SO-Ansatz meinem sehr ähnlich. Der Ansatz von nbk mit MAX() ist etwas hacky in meinen Augen, aber funktioniert.

          Kommentar

          Lädt...
          X