Ankündigung

Einklappen
Keine Ankündigung bisher.

MySQL Abfrage Zuordnung

Einklappen

Neue Werbung 2019

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

  • MySQL Abfrage Zuordnung

    Hallo,

    also ich komme nicht auf die richtige Lösung, deshalb benötige ich eure Hilfe.
    Ich habe schon alles kreuz und quer mit MAX() und ORDER BY ... DESC probiert, aber ich erhalte nicht das gewünschte Ergebnis.

    Tabelle 1 (mit fortlaufendem Datum):
    ID DATE
    1 2017-01-01
    2 2017-01-02
    3 2017-01-03
    4 2017-01-04
    5 2017-01-05
    6 2017-01-06
    7 2017-01-07
    8 2017-01-08
    9 2017-01-09
    10 2017-01-10
    11 2017-01-11
    12 ...

    Tabelle 2:
    ID DATE
    1 2017-01-01
    2 2017-01-06
    3 2017-01-10

    gewünschtes Ergebnis:
    ID DATE_1 DATE_2
    1 2017-01-01 2017-01-01
    2 2017-01-02 2017-01-01
    3 2017-01-03 2017-01-01
    4 2017-01-04 2017-01-01
    5 2017-01-05 2017-01-01
    6 2017-01-06 2017-01-06
    7 2017-01-07 2017-01-06
    8 2017-01-08 2017-01-06
    9 2017-01-09 2017-01-06
    10 2017-01-10 2017-01-10
    11 2017-01-11 2017-01-10
    12 2017-01-12 2017-01-10


    Ich hoffe ihr habt eine Vorstellung von dem, was ich meine.
    Man friert nur, wenn man glaubt, einem sei kalt

  • #2
    Geht leider nicht mit MySQL, aber ich zeige es mal dennoch

    Code:
    test=*# select * from t1;
     id |   datum    
    ----+------------
      1 | 2017-01-01
      2 | 2017-01-02
      3 | 2017-01-03
      4 | 2017-01-04
      5 | 2017-01-05
      6 | 2017-01-06
      7 | 2017-01-07
      8 | 2017-01-08
      9 | 2017-01-09
     10 | 2017-01-10
     11 | 2017-01-11
     12 | 2017-01-12
     13 | 2017-01-13
     14 | 2017-01-14
     15 | 2017-01-15
     16 | 2017-01-16
     17 | 2017-01-17
     18 | 2017-01-18
     19 | 2017-01-19
     20 | 2017-01-20
    (20 Zeilen)
    
    test=*# select * from t2;
     id |   datum    
    ----+------------
      1 | 2017-01-01
      2 | 2017-01-06
      3 | 2017-01-10
    (3 Zeilen)
    
    test=*# with range as (select daterange(datum, lead(datum) over (order by datum)) from t2) select t1.datum, lower(x.daterange) from t1 left join lateral (select * from range) x on (true) where x.daterange @> t1.datum;
       datum    |   lower    
    ------------+------------
     2017-01-01 | 2017-01-01
     2017-01-02 | 2017-01-01
     2017-01-03 | 2017-01-01
     2017-01-04 | 2017-01-01
     2017-01-05 | 2017-01-01
     2017-01-06 | 2017-01-06
     2017-01-07 | 2017-01-06
     2017-01-08 | 2017-01-06
     2017-01-09 | 2017-01-06
     2017-01-10 | 2017-01-10
     2017-01-11 | 2017-01-10
     2017-01-12 | 2017-01-10
     2017-01-13 | 2017-01-10
     2017-01-14 | 2017-01-10
     2017-01-15 | 2017-01-10
     2017-01-16 | 2017-01-10
     2017-01-17 | 2017-01-10
     2017-01-18 | 2017-01-10
     2017-01-19 | 2017-01-10
     2017-01-20 | 2017-01-10
    (20 Zeilen)
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      PHP-Code:
      SELECT
          t1
      .date,
          
      MIN(t2.date) AS date
      FROM
          t1 LEFT JOIN t2 ON 
      (t1.date >= t2.date)
      GROUP BY
         t1
      .date 
      Das würde ich aber nicht mit vielen Datensätzen machen. Der Aufwand steigt exponentiell. Performanter (sehr performant) wäre eine Variable mit laufen zu lassen. Das würde ich dann aber auch nicht zwingend in der Praxis machen.

      Könnte so aussehen: (t1 muss dazu aber sortiert sein, wenn nicht muss das in einem Subquery erfolgen)

      PHP-Code:
      SELECT
          t1
      .date,
          IF(
      t2.date IS NOT NULL, @:= t2.date, @s) AS t2_date
      FROM
          t1 LEFT JOIN
          t2 ON 
      (t1.date t2.date),
          (
      SELECT @:= ""
      *edit* fehlendes GROUP BY hinzugefügt

      Kommentar


      • #4
        in Variante 1 fehlt ein GROUP BY
        PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

        Kommentar


        • #5
          Ja, da hast du recht. Danke. Bei dir ist dafür ein lateral zuviel.

          Kommentar


          • #6
            Nein, ist es nicht. Das ist ein LATERAL JOIN - das kann MySQL nicht.

            Übrigens scheint dein erstes SQL elbst mit GROUP BY was falsches zu liefern.

            Code:
            test=*# SELECT
                t1.datum,
                MIN(t2.datum) AS date
            FROM
                t1 LEFT JOIN t2 ON (t1.datum >= t2.datum) group by t1.datum;
               datum    |    date    
            ------------+------------
             2017-01-01 | 2017-01-01
             2017-01-13 | 2017-01-01
             2017-01-04 | 2017-01-01
             2017-01-03 | 2017-01-01
             2017-01-19 | 2017-01-01
             2017-01-10 | 2017-01-01
             2017-01-15 | 2017-01-01
             2017-01-18 | 2017-01-01
             2017-01-20 | 2017-01-01
             2017-01-05 | 2017-01-01
             2017-01-06 | 2017-01-01
             2017-01-17 | 2017-01-01
             2017-01-07 | 2017-01-01
             2017-01-09 | 2017-01-01
             2017-01-12 | 2017-01-01
             2017-01-16 | 2017-01-01
             2017-01-02 | 2017-01-01
             2017-01-14 | 2017-01-01
             2017-01-08 | 2017-01-01
             2017-01-11 | 2017-01-01
            (20 Zeilen)
            Ist aber auch egal, dafür läuft es wenigstens mit MySQL

            PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

            Kommentar


            • #7
              Ich hab hier einen Vorschlag, der zu funktionieren scheint. Es gibt kein Group By Laufzeitproblem,
              allerdings ist es durch die Variable und die Sortierung eine empfindliche Lösung, muss man sehr gründlich testen. Ich habe keine Erfahrungswerte mit mySQL was die Stabilität solcher Statements angeht.

              Also ohne irgendwelche Garantien usw.:
              Code:
              MariaDB [test]>
              MariaDB [test]> select x.cdatum, x.datum,
                  ->        case when datum is not null      --
                  ->          then @varDatum := datum     -- Datum merken
                  ->          else @varDatum              -- Merkwert ausgeben
                  ->      end      as KalkuliertesDatum
                  ->   from ( /* Die Klammerung / Subselect ist wichtig für das 1. order by */
                  ->          select c.cdatum, d.datum
                  ->            from (select cdatum from tabelle1, (select @varDatum := NULL) r ) c
                  ->                          /* es können auch andere Initialisierungswerte genommen werden */
                  ->            left join tabelle2 d on c.cdatum = d.datum
                  ->          where c.cdatum > '2017/08/01' and c.cdatum < '2017/09/11'
                  ->                          /*die Datumsbeschränkung dient nur der Übersichtlichkeit */
                  ->          order by cdatum /*dieses Order by ist wichtig */
                  ->     ) x
                  -> order by cdatum;        /*dieses Order by ist nicht so wichitig */
              +------------+------------+-------------------+
              | cdatum     | datum      | KalkuliertesDatum |
              +------------+------------+-------------------+
              | 2017-08-02 | NULL       | NULL              |
              | 2017-08-03 | NULL       | NULL              |
              | 2017-08-04 | NULL       | NULL              |
              | 2017-08-05 | NULL       | NULL              |
              | 2017-08-06 | NULL       | NULL              |
              | 2017-08-07 | NULL       | NULL              |
              | 2017-08-08 | NULL       | NULL              |
              | 2017-08-09 | NULL       | NULL              |
              | 2017-08-10 | NULL       | NULL              |
              | 2017-08-11 | NULL       | NULL              |
              | 2017-08-12 | NULL       | NULL              |
              | 2017-08-13 | NULL       | NULL              |
              | 2017-08-14 | NULL       | NULL              |
              | 2017-08-15 | NULL       | NULL              |
              | 2017-08-16 | NULL       | NULL              |
              | 2017-08-17 | NULL       | NULL              |
              | 2017-08-18 | NULL       | NULL              |
              | 2017-08-19 | NULL       | NULL              |
              | 2017-08-20 | NULL       | NULL              |
              | 2017-08-21 | NULL       | NULL              |
              | 2017-08-22 | 2017-08-22 | 2017-08-22        |
              | 2017-08-23 | NULL       | 2017-08-22        |
              | 2017-08-24 | NULL       | 2017-08-22        |
              | 2017-08-25 | NULL       | 2017-08-22        |
              | 2017-08-26 | NULL       | 2017-08-22        |
              | 2017-08-27 | 2017-08-27 | 2017-08-27        |
              | 2017-08-28 | 2017-08-28 | 2017-08-28        |
              | 2017-08-29 | NULL       | 2017-08-28        |
              | 2017-08-30 | NULL       | 2017-08-28        |
              | 2017-08-31 | NULL       | 2017-08-28        |
              | 2017-09-01 | NULL       | 2017-08-28        |
              | 2017-09-02 | NULL       | 2017-08-28        |
              | 2017-09-03 | NULL       | 2017-08-28        |
              | 2017-09-04 | 2017-09-04 | 2017-09-04        |
              | 2017-09-05 | NULL       | 2017-09-04        |
              | 2017-09-06 | 2017-09-06 | 2017-09-06        |
              | 2017-09-07 | NULL       | 2017-09-06        |
              | 2017-09-08 | NULL       | 2017-09-06        |
              | 2017-09-09 | NULL       | 2017-09-06        |
              | 2017-09-10 | NULL       | 2017-09-06        |
              +------------+------------+-------------------+
              40 rows in set (0.00 sec)
              
              MariaDB [test]>
              Viel Spaß damit.

              Kommentar


              • #8
                Zitat von akretschmer Beitrag anzeigen
                Nein, ist es nicht. Das ist ein LATERAL JOIN - das kann MySQL nicht.
                Ich weiß was ein lateral join ist, hast du schonmal gezeigt. In dem Query ist der aber überflüssig.

                Zitat von akretschmer Beitrag anzeigen
                Übrigens scheint dein erstes SQL elbst mit GROUP BY was falsches zu liefern.
                Ich teste die Queries hier nicht, da schleicht sich schonmal ein Fehler ein. In dem Fall ist es umgedrehte Logik, dass Datum muss natürlich kleiner/gleich sein.

                Kommentar


                • #9
                  [X] Du hast Recht.
                  PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                  Kommentar

                  Lädt...
                  X