Announcement

Collapse
No announcement yet.

MySql Select

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • MySql Select

    Wir haben folgende Tabelle t165:


    Kennung Inhalt Nummer ID

    6580 6034 1 100
    6590 MLD 1 100
    6501 2021-12-01 1 100
    6511 X 1 100
    6580 11.23 1 200
    6590 UUU 1 200
    6501 2022-03-01 1 200
    6512 X 1 200
    6580 0.99 2 100
    6590 ZZZ 2 100
    6501 2022-03-31 2 100
    6511 X 2 100
    6580 123.45 2 200
    6590 ZZZ 2 200
    6501 2022-03-31 2 200
    6511 X 2 200

    Warum dieser Aufbau? Es gibt über 60 verschiedene Kennungen, von denen selten alle vorhanden sind. Eine Tabelle mit 60 Feldern wollten wir deshalb vermeiden. Das Datum mit der Kennung 6501 ist immer vorhanden. Es besagt, dass an diesem Tag ein Rezept ausgestellt wurde für den Patienten mit seiner ID und der Rezeptnummer. Das heisst, ein Rezept hat stets die gleiche ID und die gleiche Nummer, aber es können 60 verschiedene Feldkennungen mit entsprechendem Inhalt vorkommen.
    Für eine Statistikfunktion brauchen wir nun eine Tabelle mit festen 6 Feldkennungen pro Rezept, mit der Berechnungen durchgeführt werden sollen. Sie soll so aussehen:


    C6501 C6502 C6503 C6511 C6512 C6580

    2021-12-01 1 100 X 6034
    2022-03-01 1 200 X 11.23
    2022-03-31 2 100 X 0.99
    2022-03-31 2 200 X 123.45

    Wir haben in Vb.Net in einem ersten Schritt eine DataTable mit den Feldkennungen 6501 (Datum) erstellt. In einem zweiten Schritt sind wir DataRows dieser Table durchgegangen und haben uns die anderen Werte geholt. Das klappt gut, aber wir müssen uns zunächst die gesamte t165 in die Table holen. Und das sind in den letzten 20 Jahren mittlerweile eine halbe Million Datensätze. Wir suchen nach einem Weg, dass wir in die DataTable nur Datensätze für einem bestimmten Zeitraum aus der t165 laden. Das will uns einfach nicht gelingen. Wäre toll, wenn uns jemand einen Tipp geben könnte. Danke!

    Grüße Norbert

  • #2
    Das Tabellendesign ist unverständlich.
    Wenn es ein Feld INHALT gibt, dessen Inhalt irgendwas sein kann, ist es nicht erstaunlich, das man keine vernünftige Abfrage erstellen kann.
    Es sollte, sofern 6501 immer ein datum beinhaltet mit einem
    ...where Kennung=6501 and STR_TO_DATE(Inhalt,'%Y-%m-%d' )>Zeitraum_Start and STR_TO_DATE(Inhalt,'%Y-%m-%d' )<Zeitraum_Ende
    Christian

    Comment


    • #3
      Warum überläßt Du die Arbeit nicht dem Datenbank Server (mit einem fünffachen self-OuterJoin). Bezüglich Performance solltet Ihr mal an eine Partitionierung denken (entweder über Zeit (was auch das Löschen nach X Zeiteinheiten sehr einfach macht) oder nach KPI-Bereiche.

      Comment


      • #4
        Danke ihr beiden. Es ist immer wieder beglückend, wenn man so schnell Antworten bekommt. Tolles Forum!

        Ja, manchmal sieht man den Wald vor lauter Bäumen nicht. Natürlich kann man eine Einschränkung mit BETWEEN auf die 6501 machen und sich nur einen Teil der Daten in die DataTable holen. Dann kann man eine zweite Table mit allen übrigen Werten füllen, indem man sich in einer Schleife die ID und Nummer aus jeder Row der ersten Table holt. Das werde ich jetzt versuchen.

        Das Tabellendesign ist unverständlich.
        Das kommt sicher daher, dass die Tabelle nicht erkennbar ist.



        C6501 C6502 C6503 C6511 C6512 C6580
        2021-12-01 1 100 X 6034
        2022-03-01 1 200 X 11.23
        2022-03-31 2 100 X 0.99
        2022-03-31 2 200 X 123.45


        Georg V.
        Klingt sehr interessant. Hatte auch schon mit einer StoredProcedure geliebäugelt, um die Arbeit auf den Server zu verlagern. War mir aber dann doch zu viel Arbeit. Und mit Deinem Vorschlag (weiss gar nicht was KPI ist ) wird es bestimmt auch nicht einfacher.

        Comment


        • #5
          Nein, das kommt daher, dass die Tabellen weder normalisiert sind noch den Regeln für ein Tabellendesign entsprechen.
          Deine Spalten haben wenig aussagekräftige Namen. Das mag für dich kein Problem sein. Ein Spalte ID enthält die eindeutige ID des Datensatzen. Ansonsten heißte die Spalte REZEPT_ID.
          Deine Datensätze haben keine eindeutige ID. Hast du 2 identische Datensätze drin kannst du diese nicht mehr löschen
          Spalten enthalten irgendwas und müssen erst gecastet werden.
          ....

          Du kannst deine gewünschte Tabelle mit Subselect auf sich selbst erzeugen

          select
          (select datum from tabelle where Kennung=6501 and STR_TO_DATE(Inhalt,'%Y-%m-%d' )>Zeitraum_Start and STR_TO_DATE(Inhalt,'%Y-%m-%d' )<Zeitraum_Ende
          ) as C6501
          ,
          (select nr from tabelle where Kennung=6502 and STR_TO_DATE(Inhalt,'%Y-%m-%d' )>Zeitraum_Start and STR_TO_DATE(Inhalt,'%Y-%m-%d' )<Zeitraum_Ende
          ) as C6502
          ...
          from tabelle
          Zuletzt editiert von Christian Marquardt; 03.02.2023, 16:53.
          Christian

          Comment


          • #6
            Danke Christian,
            dass ich hier im Beispiel die Spalte ID genannnt habe geschah nur der Einfachheit halber. Ich hatte nicht angenommen, dass Du glaubst, dass ich um eine "echte" ID nicht bescheid weiss
            Mein Beispiel spiegelt bei weitem nicht den wahren Sachverhalt wider. Ich muss noch zwei andere Tabellen dazu joinen und die Anzahl der Felder ist viel größer.
            Wenn Dein Select wirklich so funktioniert, wäre es ein Segen. Ich probiers jetzt gleich aus. Melde mich dann ...

            Comment


            • #7
              Ich schnalls nicht. Hier nochmal die t165 mit echten Spaltenbezeichnungen (oben das waren nur Beispiele). Kannst Du Dein Select nochmal mit diesen Werten zeigen? Ich brauche all diese Feldkennungen (und noch ein paar mehr, ein Rezept entält ca. 60 Felder, von denen meist mur 10 ausgefüllt sind) als einen Datensatz in einer neuen Tabelle (mit vordefinierten Columns, Name wie die Kennung mit "C" davor). Hier ein Heilmittelrezept für den Patienten mit der ID 6638 (Link zur Patientenstammdatei, eindeutig!). Es ist sein 12. Rezept, ausgestellt am 03.01.23
              HLM01 HLM02 HLM03 T165_ID130
              6511 X 12 6638
              6526 X 12 6638
              6541 8 12 6638
              6520 E88.28 12 6638
              6540 MLD-45 12 6638
              6501 03.01.23 12 6638
              6581 6 12 6638
              6502 X 12 6638
              6531 X0201;X0233; 12 6638
              Bitte gib nicht auf.

              Comment


              • #8
                Nochmal zum Design:
                wenn wir vor 30 Jahren die Tabelle anders gemacht hätten (ein Datensatz pro Rezept), hätte ich es jetzt zwar einfacher, aber wir hätten eine Tabelle mit über 60 Columns, die meisten Felder leer. Ich weiss nicht was besser gewesen wäre.

                Comment


                • #9
                  select
                  (select HLM02 from tabelle where HLM03=12 and T165_ID130=6638 and HLM01='6511') as C6511
                  ,
                  (select HLM02 from tabelle where HLM03=12 and T165_ID130=6638 and HLM01='6526') as C6526
                  ...
                  from tabelle

                  Sicherlich ein Datensatz je Rezept, die Problem siehst du jetzt
                  Christian

                  Comment


                  • #10
                    select(select HLM02 from t165 where HLM03=12 and T165_ID130=6638 and HLM01='6511') as C6511,(select HLM02 from t165 where HLM03=12 and T165_ID130=6638 and HLM01='6526') as C6526 from t165

                    bringt mir als Ergebnis 29603 Datensätze mit 2 Feldern (alle leer Memo)
                    C6511 C6526
                    (Memo) (Memo)
                    (Memo) (Memo)

                    Comment


                    • #11
                      Was ergibt ein einzelner SQl aus dem Subeselect
                      select HLM02 from t165 where HLM03=12 and T165_ID130=6638 and HLM01=6511
                      Das sollte X ergeben

                      Ev. and HLM01=6511 ohne ' '
                      Christian

                      Comment


                      • #12
                        1 Row, 1 Column 'HLM02' als (Memo) leer
                        Navicat 8 for MySQL zeigt es zumindest so an.

                        Comment


                        • #13
                          Fehler gefunden: es gibt keine ID 6638
                          hatte mich vertippt, es gibt nur 6538
                          Teste jetzt gleich Dein Select nochmal.
                          Entschuldige bitte tausendmal ...





                          Comment


                          • #14
                            Ich weiß nicht wer Navicat 8 ist, aber man sollte schon das Tool des Herstellers nutzen
                            https://www.mysql.com/products/workbench/

                            Des Weiteren, wenn
                            HLM03
                            T165_ID130
                            HLM01
                            nummerisch sind muss der SQL
                            select HLM02 from t165 where HLM03=12 and T165_ID130=6638 and HLM01=6511
                            X ergeben
                            Christian

                            Comment


                            • #15
                              Select bringt jetzt 29603 Datensätze
                              C6511='X'
                              C6526='X'
                              in jeder Row
                              Ist das richtig so?
                              Übrigens: HLM01 ist ein varchar, feste Länge=4
                              Hattest es ja auch bei Deinem Select in ' ' gesetzt.

                              Comment

                              Working...
                              X