Bernd: Einträge nach Jahre ein-/ ausblenden

Hallo,

kann ich wenn ich z.B. in einem Filter 2018 übergebe in meiner Datenbank alle Einträge suchen die das Jahr 2018 im Datum haben?

Das Feld hat leider varchar(10) und kann derzeit nicht einfach so geändert werden. Das Datum steht so drin 10.06.2018

Ansonsten müsste ein weiteres Feld anlegen wo nur das Jahr drin steht. Das Update könnte ich über PHP und einem ChronJob erledigen.

  1. Tach!

    kann ich wenn ich z.B. in einem Filter 2018 übergebe in meiner Datenbank alle Einträge suchen die das Jahr 2018 im Datum haben?

    Das Feld hat leider varchar(10) und kann derzeit nicht einfach so geändert werden. Das Datum steht so drin 10.06.2018

    Ja, recht ineffizientm weil dazu ein Full-Table-Scan stattfinden muss. Mit den Stringfunktionen von MySQL kannst du den Teil des Jahres ermitteln und dann mit dem Wert vom Filter vergleichen. Eigentlich müsste schon LIKE '%.2018' oder LIKE '__.__.2018' gehen.

    dedlfix.

    1. Hallo,

      ich habe noch eine Frage. Für einen weitern Filter nutze ich folgendes

      $values = $teile25;
      $empfaengerListe = '"' . implode( '", "', $values ) . '"';
      
      Projekt IN (" . $empfaengerListe . ")
      

      Kann ich dieses auch mit LIKE machen? Denn auch da kann es sein, dass ich mehrere Jahre mit Anzeigen möchte.

      1. Ok, so sollt es gehen

        SELECT * 
        FROM  `projekte` 
        WHERE  `von` REGEXP  '2017|2018'
        LIMIT 0 , 30
        

        Jetzt ist nur noch die Frage wie ich den | in meine Abfrage bekomme.

        1. Hello,

          Not Ok, so sollte es nicht gemacht werden

          SELECT * 
          FROM  `projekte` 
          WHERE  `von` REGEXP  '2017|2018'
          LIMIT 0 , 30
          

          Wenn schon simpel, dann so

          SELECT * 
          FROM  `projekte` 
          WHERE  `von` LIKE '%.2017' OR `von` LIKE '%.2018'
          LIMIT 0 , 30
          

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Hallo,

            das kann ich so aber nicht umsetzten? Ich weiß ja nicht wie viele Filter in diesem Fall Jahre aktiviert sind, dann müsste ich das OR ja irgendwie dynamisch hinzufügen?

            Und warum sollte ich REGEXP nicht nutzen? Dieses wird auf der mysql.com Seite selbst vorgeschlagen? https://dev.mysql.com/doc/refman/5.7/en/regexp.html

            1. Hello,

              das kann ich so aber nicht umsetzten? Ich weiß ja nicht wie viele Filter in diesem Fall Jahre aktiviert sind, dann müsste ich das OR ja irgendwie dynamisch hinzufügen?

              Ja, klar. Den SQL-String kannst Du doch mit PHP zusammensetzen lassen.

              Glück Auf
              Tom vom Berg

              --
              Es gibt nichts Gutes, außer man tut es!
              Das Leben selbst ist der Sinn.
              1. Hallo,

                Ja, klar. Den SQL-String kannst Du doch mit PHP zusammensetzen lassen.

                meine Funktion ist so aufgebaut

                function uebersicht($mysqli, $teile25, $teile26, $filter=false, $s=false) {
                
                 $values = $teile25;
                 $empfaengerListe = '"' . implode( '", "', $values ) . '"';
                 
                 $values_jahre = $teile26;
                 $jahreListe = '"' . implode( '", "', $values_jahre ) . '"';
                
                }
                

                wie kann ich hier das jetzt automatisch zusammenbauen lassen?

                1. Hello,

                  Ja, klar. Den SQL-String kannst Du doch mit PHP zusammensetzen lassen.

                  meine Funktion ist so aufgebaut

                  function uebersicht($mysqli, $teile25, $teile26, $filter=false, $s=false) {
                  
                   $values = $teile25;
                   $empfaengerListe = '"' . implode( '", "', $values ) . '"';
                   
                   $values_jahre = $teile26;
                   $jahreListe = '"' . implode( '", "', $values_jahre ) . '"';
                  
                  }
                  

                  wie kann ich hier das jetzt automatisch zusammenbauen lassen?

                  Bitte um vollständige Doku.
                  Welche Daten werden in welcher Form in welchem Funktionsargument übergeben?

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt nichts Gutes, außer man tut es!
                  Das Leben selbst ist der Sinn.
                  1. Hallo,

                    Bitte um vollständige Doku.
                    Welche Daten werden in welcher Form in welchem Funktionsargument übergeben?

                    in $jahreListe steht z.B. 2017, 2018 oder nur 2019 was auch immer der User angeklickt hat.

                    1. Hello,

                      Bitte um vollständige Doku.
                      Welche Daten werden in welcher Form in welchem Funktionsargument übergeben?

                      in $jahreListe steht z.B. 2017, 2018 oder nur 2019 was auch immer der User angeklickt hat.

                      Du bekommst an dieser Stelle also eine Kommaseparierte Liste? Wo wird die denn wie in Empfang genommen (Request) und wie sieht das HTML-Formular dazu aus? Sind die Daten schon entgiftet?

                      SQL-Escaping sollten wir hier nicht vergessen!

                      Wenn also in der Liste z. B. steht: "2016,2017,2019", dann kannst Du daraus auch mit str_replace() arbeiten.

                      $sql = 'where `von` LIKE "%.' . str_replace (',', '" OR `von` LIKE "%.' , $liste ) . '"';  
                      

                      Ich hoffe, so stimmt es. Lass Dir den SQL-String nochmal anzeigen zum Debug.
                      Und über das Escaping noch nachdenken. Und Sonderfall, wenn gar nichts in der Liste steht, behandeln.

                      Du

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt nichts Gutes, außer man tut es!
                      Das Leben selbst ist der Sinn.
            2. Hallo Bernd,

              Und warum sollte ich REGEXP nicht nutzen?

              Zeichenketten mithilfe regulärer Ausdrücke zu prüfen, ist sehr rechenintensiv. Sie sollten nur dann verwendet werden, wenn einfache Stringvergleiche nicht ausreichen.

              Bis demnächst
              Matthias

              --
              Pantoffeltierchen haben keine Hobbys.
              ¯\_(ツ)_/¯
              1. Zeichenketten mithilfe regulärer Ausdrücke zu prüfen, ist sehr rechenintensiv.

                Reguläre Ausdrücke werden zu nicht-deterministischen endlichen Automaten kompiliert, dann in determinitische Automaten überführt und manchmal noch minimiert. Das ist komplexitätstheoretisch teuer, aber es gibt zwei Abers: Die schlechte Komplexitätsschranke der Transformation wird in der Praxis meist unterboten, man muss eher pathologische Beispiele konstruieren, um die Schranke wirklich auszureizen. Das zweite sehr viel größere Aber: Die Schranke ist abhängig von der Größe des regulären Ausdrucks, nicht von den Strings, die der reguläre Ausdruck schlussendlich erkennen soll. Das Wort-Problem für reguläre Ausdrücke ansich ist im Worstcase in Linearzeit lösbar. Das bedeutet auch, dass der Overhead für die Konstruktion des DFAs nur einmal vorab anfällt, egal wieviele Strings damit verglichen werden.

                Soviel zur Effizienz (im theoretischen Sinne). Ob das von einem System auch performant gelöst ist, kommt ganz auf die Implementierung an, davon habe ich aber absolut keine Ahnung.

                Sie sollten nur dann verwendet werden, wenn einfache Stringvergleiche nicht ausreichen.

                Auch auf die Gefahr hin mich hier zu wiederholen: Performance-Optimierung sollte erst betrieben werden, wenn es schon zu spät ist. Optimierung auf Verdacht ist ineffizient, ineffektiv und im schlimmsten Fall sogar kontraproduktiv. Beim Schreiben von Code sollte immer zuerst die Lesbarkeit im Fokus stehen.

      2. Tach!

        $values = $teile25;
        $empfaengerListe = '"' . implode( '", "', $values ) . '"';
        
        Projekt IN (" . $empfaengerListe . ")
        

        Kann ich dieses auch mit LIKE machen?

        Kann ich für deinen Fall nicht beantworten, weil ich die Daten nicht kenne. PHP-Code ist auch für Datenbankprobleme nicht relevant. Für LIKE müssen die Daten einen gemeinsamen Teil haben. IN() kann mehrere unterschiedliche Werte enthalten. Das lässt sich nicht unbedingt austauschen.

        dedlfix.

    2. Ja, recht ineffizientm weil dazu ein Full-Table-Scan stattfinden muss.

      Den Full-Table-Scan hast Du auch mit einer Datumsfunktion die das Jahr ermittelt. Denn ein Index greift nur, wenn er in seiner gesamten Länge passt. Also bspw. wenn es für das Jahr ein eigenes Feld gibt und auf diesem Feld ein Index liegt. MFG

      1. Hello,

        Ja, recht ineffizientm weil dazu ein Full-Table-Scan stattfinden muss.

        Den Full-Table-Scan hast Du auch mit einer Datumsfunktion die das Jahr ermittelt. Denn ein Index greift nur, wenn er in seiner gesamten Länge passt. Also bspw. wenn es für das Jahr ein eigenes Feld gibt und auf diesem Feld ein Index liegt.

        Das ist auch schon wieder eine uneidliche Falschaussage und stellt eine Behinderung der Programmprofessionalität dar!

        Indexe können grundsätzlich genutzt werden, wenn der gesuchte Anteil formatbekannt in Indexrichtung vorne steht, also auch, wenn in Indexrichtung (hier von links nach rechts) nur ein Teil benutzt werden kann.

        Gute DBMS konnten das schon vor über 35 Jahren!

        Glück Auf
        Tom vom Berg

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
        1. Indexd können grundsätzlich genutzt werden, wenn der gesuchte Anteil formatbekannt in Indexrichtung vorne steht, also auch, wenn in Indexrichtung (hier von links nach rechts) nuf ein Teil benutzt werden kann.

          Beweise Deine Behauptung. Im Übrigen steht das Jahr nicht vornedran sondern hintendran. MFG

          PS: Selbst wenn Deine Behauptung stimmen würde wäre die Durchfüuhrung nicht empfehlenswert. Die Begründung, daß ein solchs Design schlecht ist, hast Du selbst geliefert: hier

      2. Tach!

        Ja, recht ineffizientm weil dazu ein Full-Table-Scan stattfinden muss.

        Den Full-Table-Scan hast Du auch mit einer Datumsfunktion die das Jahr ermittelt.

        Kann sein, kommt darauf an, wie das intern umgesetzt ist. Wenn das Datum sortierfähig abgelegt ist, entspricht ein Jahr einem Zeitraum vom 1.1. bis 31.12. inklusive. Das könnte also auf einen Bereich umgerechnet werden und dann könnte der Index genommen werden. Machte meine schon etwas ältere Test-MariaDB aber nicht.

        Denn ein Index greift nur, wenn er in seiner gesamten Länge passt.

        Diese Aussage ist nicht richtig, jedenfalls nicht so uneingeschränkt, wie du es hier formulierst. Ein Index kann und wird beispielsweise kann bei einem LIKE 'xxx%' verwendet werden, also wenn der Anfang des Suchwortes bekannt ist. Bei einem Datum wäre das für das Jahr dann der Fall, wenn es wenigstens als sortierfähiger String gespeichert wäre, also als YYYY-MM-DD formatiert.

        dedlfix.

        1. like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet. MFG

          1. Hello,

            like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet.

            Das ist ja eine hochmoderne Version.

            Und zeig bitte mal das Create-Statement der Testtabelle.

            Glück Auf
            Tom vom Berg

            --
            Es gibt nichts Gutes, außer man tut es!
            Das Leben selbst ist der Sinn.
            1. Hi,

              like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet.

              Das ist ja eine hochmoderne Version.

              ich weiß gar nicht, was Du hast, die ist doch nicht mal 10 Jahre alt (12.10.2009).

              cu,
              Andreas a/k/a MudGuard

          2. Tach!

            like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet.

            Wer weiß, warum das bei dir nicht der Fall ist, aber ich bekomme das hin. Die Daten sind irgendwelche Test-Daten, die ich irgendwann mal im Netz gefunden habe. Die Tabelle hat circa 300.000 Datensätze. Ein Grund für eine Index-Nichtverwendung kann sein, dass die Datenmenge zu klein ist und es schneller mit dem Full-Table-Scan ist als mit Indexverwendung.

            EXPLAIN SELECT * FROM `employees` WHERE last_name LIKE 'ka%'
            

            id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra 1 | SIMPLE | employees | range | last_name | last_name | 18 | NULL | 6134 | Using index condition

            CREATE TABLE `employees` (
              `emp_no` int(11) NOT NULL,
              `birth_date` date NOT NULL,
              `first_name` varchar(14) NOT NULL,
              `last_name` varchar(16) NOT NULL,
              `gender` enum('M','F') NOT NULL,
              `hire_date` date NOT NULL
            ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
            
            ALTER TABLE `employees`
              ADD PRIMARY KEY (`emp_no`),
              ADD KEY `last_name` (`last_name`);
            

            dedlfix.

            1. Hi,

              like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet.

              Wer weiß, warum das bei dir nicht der Fall ist, aber ich bekomme das hin.

              Kann gar nicht sein, pl hat doch alle möglichen Szenarien durchgespielt - sonst wäre das immer ja nicht die Wahrheit.

              cu,
              Andreas a/k/a MudGuard

              1. Hello,

                like macht immer einen Full-Table-Scan (v: 5.1.40-community). Hab ich eben getestet.

                Wer weiß, warum das bei dir nicht der Fall ist, aber ich bekomme das hin.

                Kann gar nicht sein, pl hat doch alle möglichen Szenarien durchgespielt - sonst wäre das immer ja nicht die Wahrheit.

                Ich vermute eher, dass er gar keinen passenden Index angelegt hatte auf seine 50 Testdatensätze. ;-P

                Ja, ich schäme mich auch für das Fastmobbing. :-O

                Glück Auf
                Tom vom Berg

                --
                Es gibt nichts Gutes, außer man tut es!
                Das Leben selbst ist der Sinn.
  2. n'Abend,

    kann ich wenn ich z.B. in einem Filter 2018 übergebe in meiner Datenbank alle Einträge suchen die das Jahr 2018 im Datum haben?

    da du die Frage so provozierend formuliert hast:
    Ich weiß nicht, ob du das kannst. Aber es geht. ;-)

    Das Feld hat leider varchar(10) und kann derzeit nicht einfach so geändert werden.

    Klingt nach einem ungünstigen Design. Ich würde mir an deiner Stelle überlegen, ob das nicht doch geändert werden könnte. Aber ...

    Das Datum steht so drin 10.06.2018

    Dann bliebe noch der Mustervergleich mit LIKE "%2018".

    Ansonsten müsste ein weiteres Feld anlegen wo nur das Jahr drin steht. Das Update könnte ich über PHP und einem ChronJob erledigen.

    Da würde ich eher die Spalte fürs Datum in den Typ DATE ändern.
    Übrigens: Der Cronjob schreibt sich ohne 'h', obwohl Wörter wie chronisch oder chronologisch alle mit 'ch' geschrieben werden. Sogar im Englischen.

    So long,
     Martin

    --
    Ein Tag, an dem du nicht wenigstens einmal gelacht hast, ist ein verlorener Tag.
  3. Hello,

    [siehe Dedlfix]

    Und wenn die Abfrage öfter stattfinden soll, dann kannst Du tatsächlich besser eine neue Spalte anlegen mit der Jahreszahl oder gleich dem Datum in ANSI-Schreibweise und drei Trigger für insert, update und delete auf die varchar()-Spalte legen, damit die MySQL-Datum-Spalte automatisch geführt wird.

    PHP oder ein CronJob sind das falsche Mittel dafür. Trigger sind hier besser!

    Glück Auf
    Tom vom Berg

    --
    Es gibt nichts Gutes, außer man tut es!
    Das Leben selbst ist der Sinn.
  4. Hallo,

    danke für eure Antworten. Ich habe folgendes getestet und es funktioniert

    SELECT * 
    FROM  `projekte` 
    WHERE  `von` LIKE  '%.2019'
    

    Und wenn die Abfrage öfter stattfinden soll, dann kannst Du tatsächlich besser eine neue Spalte anlegen mit der Jahreszahl

    Die Übersichtsseite wo der Filter angewendet wird, wird pro Tag sehr oft aufgerufen.

    Klingt nach einem ungünstigen Design. Ich würde mir an deiner Stelle überlegen, ob das nicht doch geändert werden könnte.

    Im Herbst, sollte ich dieses noch erleben wird eine neue Version online gestellt, da sind solche Fehler behoben. Derzeit muss ich aus dem was seit Jahren immer mal wieder weiterentwickelt wird das beste machen.

    1. Hello,

      Die Übersichtsseite wo der Filter angewendet wird, wird pro Tag sehr oft aufgerufen.

      Um wieviele Datensätze handelt es sich ungefähr?

      Wenn es wirklich sehr viele sind, würde ich mir das mit der zusätzlichen Spalte, einmal füllen lassen, und den Triggern doch mal überlegen. Das Verfahren hätte den Vorteil, dass die übrige Applikation nichts davon mitbekommt, also nicht geändert werden muss. Das ist ja bei verkorkstem Design i. d. R. recht aufwändig.

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
      1. Hallo,

        Um wieviele Datensätze handelt es sich ungefähr?

        derzeit sind es 506 Einträge. Es kommen jedes Jahr ca. 150 / 200 hinzu.

        1. Hello,

          Um wieviele Datensätze handelt es sich ungefähr?

          derzeit sind es 506 Einträge. Es kommen jedes Jahr ca. 150 / 200 hinzu.

          Na dann ...
          Wenn das die Obermennge ist und nicht die gefiltette. Das reitet das DBMS ja noch auf 10 Bit ab ;-)
          Da lohnt es nicht, weiter Energie drauf zu verschwenden.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Hallo,

            Voraussetzungen für den folgenden Vorschlag:

            • MySQL 5.7
            • InnoDB
            • Das Datum ist Fixformat, d.h immer dd.mm.yyyy. Ausreißer wie "3.4.2019" oder "17.05.19" dürfen nicht vorkommen.

            In diesem Fall könnte sich für die Jahreszahl eine virtuelle generated column lohnen, über die man den Jahresfilter erzeugt.

            Die fügt man mit einem ALTER hinzu, und man kann sie auch indexieren.

            Bei 500 Zeilen ist der Nutzen aber tatsächlich fraglich...

            Rolf

            --
            sumpsi - posui - clusi
    2. SELECT * 
      FROM  `projekte` 
      WHERE  `von` LIKE  '%.2019'
      

      Du hattest doch mehrere Jahre?

      Wie wäre denn diese Lösung mit dem IN():

      select * 
      from `projekte`
      where SUBSTRING(von,7) IN ("2018","2019","2015");
      

      Gruß, Linuchs

      1. Hello Linuchs,

        prinzipiell eine gute Idee.

        SELECT * 
        FROM  `projekte` 
        WHERE  `von` LIKE  '%.2019'
        

        Du hattest doch mehrere Jahre?

        Wie wäre denn diese Lösung mit dem IN():

        select * 
        from `projekte`
        where SUBSTRING(von,7) IN ("2018","2019","2015");
        

        ich würde dann aber

        trim(substring(von, -4)) IN (...) 
        

        bevorzugen. Wer weiß schon, ob da nicht auch mal "8.2.1958" drinsteht?

        Und nochmals die Ermahnung, die Datenherkunft zu beachten und SQL-Injection zu verhindern

        Glück Auf
        Tom vom Berg

        --
        Es gibt nichts Gutes, außer man tut es!
        Das Leben selbst ist der Sinn.
  5. Das Feld hat leider varchar(10) und kann derzeit nicht einfach so geändert werden. Das Datum steht so drin 10.06.2018

    Nun, so nimm eine Stringfunktion. Und wenn es ein Datumsfeld wäre, würdest Du eine Datumsfunktion nehmen. Das wäre der Unterschied. MFG

    1. Hello,

      Das Feld hat leider varchar(10) und kann derzeit nicht einfach so geändert werden. Das Datum steht so drin 10.06.2018

      Nun, so nimm eine Stringfunktion. Und wenn es ein Datumsfeld wäre, würdest Du eine Datumsfunktion nehmen. Das wäre der Unterschied.

      Das ist leider wieder nur die halbe Wahrheit!

      Der Sinn von Datentypen steckt unter Anderem auch in

      • Formatsicherheit
      • Sortierbarkeit durch (eingeschränkte) Ordinalität
      • Indexierbarkeit

      Wenn man Kalender-/Zeitdaten also formatfrei in "normalen" Stringfeldern ablegt, dann sind sie nicht einfach zu sortieren und damit nicht indexierbar.

      Glück Auf
      Tom vom Berg

      --
      Es gibt nichts Gutes, außer man tut es!
      Das Leben selbst ist der Sinn.
      1. Wenn man Kalender-/Zeitdaten also formatfrei in "normalen" Stringfeldern ablegt, dann sind sie nicht einfach zu sortieren und damit nicht indexierbar.

        Auch falsch. MFG

        1. Hallo pl,

          sagen wir: halb richtig. Ein Datum im dd.mm.yyyy Format kann man zwar indexieren, aber es nützt nicht viel.

          Ein Datum im yyyy-mm-dd Format kann man prima indexieren und der Index nützt auch eine Menge. Das hilft Bernd nur leider nicht.

          Ich denke, was Bernd jetzt am meisten hilft, ist die SUBSTRING-Alternative, und Tipps, wie man das nötige SQL dazu generiert. Die Table ist klein genug, um einen Fullscan tolerieren zu können, und im Herbst soll ja die sanierte Version live gehen.

          Rolf

          --
          sumpsi - posui - clusi
          1. Hello,

            sagen wir: halb richtig. Ein Datum im dd.mm.yyyy Format kann man zwar indexieren, aber es nützt nicht viel.

            Mit MySQL/MariaDB nicht sinnvoll möglich.

            In anderen DBMSen Ohne definiertes Format auch nur aufwändig möglich und unsicher. Mit definiertem Format (in dieser Form) auch nur dann möglich. wenn das DBMS zur Indexierung Funktionen zulässt. dBase konnte sowas übrigens.

            Ich denke, was Bernd jetzt am meisten hilft, ist die SUBSTRING-Alternative, und Tipps, wie man das nötige SQL dazu generiert. Die Table ist klein genug, um einen Fullscan tolerieren zu können, und im Herbst soll ja die sanierte Version live gehen.

            Genau das hat Linuchs doch schon vorgeschlagen, ich habe noch eineinhalb Schritte weitergedacht. Nun fehlt nur noch die Funktion. Dazu benötigen wir von Bernd noch Auskunft über den Datenpfad (die Datenherkunft und alle Schritte bis zur Liste), um auch SQL-Injection ausschließen zu können.

            Das entschuldigt aber nicht pls Trumpismus mit den unsubstantiierten Kurzaussagen.

            Glück Auf
            Tom vom Berg

            --
            Es gibt nichts Gutes, außer man tut es!
            Das Leben selbst ist der Sinn.
            1. Hallo,

              Nun fehlt nur noch die Funktion. Dazu benötigen wir von Bernd noch Auskunft über den Datenpfad (die Datenherkunft und alle Schritte bis zur Liste), um auch SQL-Injection ausschließen zu können.

              die Daten kommen aus dieser Abfrage

              $stmtVaFilterr = $mysqli->prepare("
                    SELECT id, userid, jahr FROM va_settings  WHERE userid=?");
                  
              $stmtVaFilterr->bind_param("s", $object->user_code);
              $stmtVaFilterr->execute();
              $stmtVaFilterr->bind_result($id, $userid, $jahr);
              
              while($stmtVaFilterr->fetch()) {
                  $teile26[] = $jahr;
              }
              

              und wird dann an diese Funktion wie gestern Abend geschrieben übergeben

              function uebersicht($mysqli, $teile25, $teile26, $filter=false, $s=false) {
              
               $values = $teile25;
               $empfaengerListe = '"' . implode( '", "', $values ) . '"';
               
               $values_jahre = $teile26;
               $jahreListe = '"' . implode( '", "', $values_jahre ) . '"';
              
              }
              
              1. Hallo Bernd,

                wenn deine Jahreszahlen aus va_settings kommen, dann gibt es einen reinen SQL Weg. Er setzt natürlich voraus, dass die Spalte jahr in deiner va_settings Tabelle ausschließlich vierstellige Jahreszahlen enthält.

                SELECT *
                FROM   projekte
                WHERE  SUBSTR(von, -4) IN (SELECT jahr FROM va_settings WHERE userid=?);
                

                Performant ist das nicht, das liegt aber am Format von von. Ein Datenmodell mit einer DATE-Spalte wäre hier auch nicht unbedingt besser, weil mysql dann pro Row die Jahreszahl aus dem Date herausrechnen muss. Für beste Performance sollte das Jahr in einer berechneten, materialisierten Spalte stehen (-> SQL Handbuch: generated column mit STORED Schlüsselwort). Eine generated column hat den Vorteil, dass MYSQL sie für dich aktuell hält, du musst nichts dafür tun. Eine stored column kann man auch problemlos indexieren.

                Rolf

                --
                sumpsi - posui - clusi
                1. Hello,

                  wenn deine Jahreszahlen aus va_settings kommen, dann gibt es einen reinen SQL Weg. Er setzt natürlich voraus, dass die Spalte jahr in deiner va_settings Tabelle ausschließlich vierstellige Jahreszahlen enthält.

                  SELECT *
                  FROM   projekte
                  WHERE  SUBSTR(von, -4) IN (SELECT jahr FROM va_settings WHERE userid=?);
                  
                  SELECT *
                  FROM   projekte
                  WHERE  SUBSTR(TRIM(von), -4) IN (SELECT jahr FROM va_settings WHERE userid=?);
                  

                  Ich würde es auch hier um das TRIM() ergänzen, und zwar diesmal an der richtigen Stelle ☆ähem☆. Ob das DMNS bei VarChar() selber trimmt, bin ich immer unsicher. Schaden kann's aber sicherlich nicht.

                  Glück Auf
                  Tom vom Berg

                  --
                  Es gibt nichts Gutes, außer man tut es!
                  Das Leben selbst ist der Sinn.
                  1. Guten Morgen,

                    danke euch beiden.

                    SELECT *
                    FROM   projekte
                    WHERE  SUBSTR(TRIM(von), -4) IN (SELECT jahr FROM va_settings WHERE userid=?);
                    

                    das heißt ich muss die Werte gar nicht meine Funktion übergeben und kann es direkt einfügen?

                    1. Hello,

                      danke euch beiden.

                      Gerne geschehen.

                      SELECT *
                      FROM   projekte
                      WHERE  SUBSTR(TRIM(von), -4) IN (SELECT jahr FROM va_settings WHERE userid=?);
                      

                      das heißt ich muss die Werte gar nicht meine Funktion übergeben und kann es direkt einfügen?

                      Du musst dann nur das Ergebnis des SQL-Requests verarbeiten. Da habe ich im Moment den Überblick verloren, wie das in deine Skriptlandschaft eingebettet ist.

                      Glück Auf
                      Tom vom Berg

                      --
                      Es gibt nichts Gutes, außer man tut es!
                      Das Leben selbst ist der Sinn.
                    2. Hallo Bernd,

                      auch gern geschehen 😀

                      Den TRIM hatte ich nicht drin, weil Spaces am Ende eines Wertes vom = Operator ignoriert werden. Aber es schadet nichts.

                      Ob die Abfrage für dich passt, probierst du am besten im phpmyadmin aus. Denk nur dran, dass SELECT * nicht in Programme gehört. Man listet die Feldnamen explizit auf.

                      Rolf

                      --
                      sumpsi - posui - clusi
      2. @@TS

        Wenn man Kalender-/Zeitdaten also formatfrei in "normalen" Stringfeldern ablegt, dann sind sie nicht einfach zu sortieren und damit nicht indexierbar.

        Das kommt darauf an, welches Datumsformat man verwendet:

        the good | 2019-06-11 | bestens sortierbar the ugly | 11.06.2019 | nicht sortierbar the bad | 6/11/19 | völlig durcheinander

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Hello,

          @@TS

          Wenn man Kalender-/Zeitdaten also formatfrei in "normalen" Stringfeldern ablegt, dann sind sie nicht einfach zu sortieren und damit nicht indexierbar.

          Das kommt darauf an, welches Datumsformat man verwendet:

          the good | 2019-06-11 | bestens sortierbar the ugly | 11.06.2019 | nicht sortierbar the bad | 6/11/19 | völlig durcheinander

          Da fehlen uns einfach die Angaben zum Format. Im ersten und zweiten Fall kann man sie einschätzen im driiten nur erraten. Mit einem geeigneten Algorithmus wären die Records aber sortierbar, wenn deren Teilelemente benannt werden.

          Beim Datum im ANSI-Format kann der Algorithmus sogar entfallen. Es wäre direkt sortierbar.

          Ja, darum schrieb ich auch "formatfrei". Man weiß also nichts über das jeweilige Format, und das könnte dann sogar von Reihe zu Reihe auch noch wechseln.

          Die Formalisierung der Datenanordnung hat auch für die Indexierung nur dann einen Sinn, wenn man die Daten damit ordinalisieren kann, also die Vorgänger und die Nachfolger für den jeweiligen Wert vorhersagbar sind. Für die Indexierung müssen sie allerdings nicht zwingend in der Menge vorhanden sein, nur wenn sie auftreten, steht ihr relativer Platz schon fest.

          Glück Auf
          Tom vom Berg

          --
          Es gibt nichts Gutes, außer man tut es!
          Das Leben selbst ist der Sinn.
          1. Da fehlen uns einfach die Angaben zum Format.

            Das Format hat er geliefert und zwar beim ersten post. Die Angaben zum Format sind also vorhanden.

            MFG

            1. Hello,

              Da fehlen uns einfach die Angaben zum Format.

              Das Format hat er geliefert und zwar beim ersten post. Die Angaben zum Format sind also vorhanden.

              Mein Posting bezog sich auf Gunnars Tabelle. Die enthält zwar Datenbeispiele, aber keine Formatbeschreibungen.

              Glück Auf
              Tom vom Berg

              --
              Es gibt nichts Gutes, außer man tut es!
              Das Leben selbst ist der Sinn.