Ankündigung

Einklappen
Keine Ankündigung bisher.

FIND_IN_SET komplexe Mehrfachsortierung

Einklappen

Neue Werbung 2019

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

  • DanielB
    hat ein Thema erstellt FIND_IN_SET komplexe Mehrfachsortierung.

    FIND_IN_SET komplexe Mehrfachsortierung

    Hallo zusammen,

    ich hoffe hier gibt es jemand, der etwas entspannter mit komplexen MySql-Querys jonglieren kann

    PHP-Code:
    $sum strtotime(date("d-m-Y"strtotime("$today")) . " -30 days");
    $verfallsdatum date('d-m-Y',$sum);

    $query "SELECT *, DATE_FORMAT(datum,'%d-%m-%Y') AS datumfeld FROM tabelle WHERE datum >= $verfallsdatum ";

    // formulardaten aus zwei Dropdowns:
    if ($rubriken != ""$query .= " WHERE art='$rubriken'";

    if (
    $rubriken == "" && $herkunft !=""$query .= " AND land='$herkunft'";

    if (
    $rubriken != "" && $herkunft !=""$query .= " AND land='$herkunft'";

    // suchfunktion aus forumular:

    if ($suche != "" && $rubriken != "" || $herkunft !="") {
    $query .= " AND beschreibung LIKE \"%$suche%\" "
    }
    elseif (
    $suche != "") {
        
    $query .= " AND beschreibung LIKE \"%$suche%\" ";
    }


    $query .= " ORDER BY FIND_IN_SET(typ,'NULL,kategorie1,ketegorie3,kategorie2') DESC LIMIT ".intval($start).",".intval($limit); 
    Frage 1)
    Ich will jetzt zusätzlich noch nach Datum sortieren....

    Frage 2)
    Es ist wichtig, dass die Kategorien (1-3) nach Blöcken im Array sortiert stehen und dabei nach Datum in den Blöcken sortiert sind.

    Frage 3)
    Kategorie1 soll 5 Tage (von $today)
    Kategorie3 soll 1 Tag (von $today)
    ... unter den ersten Einträgen im Array so weit wie möglich vorne stehen.

    Frage 4)
    Ich hatte ursprünglich ein Problem als ich das Datum als 10.04.2010 und nicht 10-04-2010 verwande.
    Ich hab dann mit ein paar escape-funktionen gearbeitet, die mir aber dann irgendwie immer was anderes weg-escapet haben .. nur nicht die Punkte in der Variable $verfallsdatum
    (muss ... datum >= '$verfallsdatum' heißen oder ohne Hochkommata?)

    Da ich bestehenden Code (hier nicht abgebildet) aufgrund größerem Aufwand nicht umbauen will, sondern nur das Array konstruieren will, würde ich das gerne soweit möglich mit MySql und wenn nötig mit Array-Funktionen lösen.

    Wäre echt super, wenn hier jemand weiß, wie ich das Puzzel am besten baue. Hab schon länger dran "gelernt"

  • Gast-Avatar
    Ein Gast antwortete
    Da mir das Problem immer noch nicht ganz klar ist, habe ich mal
    ein Beispiel zusammen gestellt.

    Code:
    CREATE TABLE test_daten (
     id INT NOT NULL,
     kategorie INT NOT NULL,
     datum DATE NOT NULL
    );
    
    -- Kategorie 1 = Premium,  3 = Basis,  9 = Gratis
    
    INSERT INTO test_daten VALUES
    ( 1, 1, '2010-04-08' ),
    ( 2, 1, '2010-04-09' ),
    ( 3, 1, '2010-04-10' ),
    ( 4, 1, '2010-04-11' ),
    ( 5, 1, '2010-04-12' ),
    ( 6, 1, '2010-04-13' ),
    ( 7, 3, '2010-04-08' ),
    ( 8, 3, '2010-04-09' ),
    ( 9, 3, '2010-04-10' ),
    (10, 3, '2010-04-11' ),
    (11, 3, '2010-04-12' ),
    (12, 3, '2010-04-13' ),
    (13, 9, '2010-04-08' ),
    (14, 9, '2010-04-09' ),
    (15, 9, '2010-04-10' ),
    (16, 9, '2010-04-11' ),
    (17, 9, '2010-04-12' ),
    (18, 9, '2010-04-13' );
    
    -- Max. 10 Anzeigen,  
    
    -- Kat. 1: gültig heute bis -4 Tage
    SELECT 1 AS temp_kat, kategorie, datum, id 
      FROM test_daten
    WHERE kategorie = 1
      AND datum BETWEEN CURRENT_DATE - 4 AND CURRENT_DATE
    
    UNION 
    
    -- Kat. 3: gültig heute 
    SELECT 3 AS temp_kat, kategorie, datum, id 
      FROM test_daten
     WHERE kategorie = 3
       AND datum BETWEEN CURRENT_DATE AND CURRENT_DATE
       
    UNION 
    
    -- wenn das Datum angelaufen ist, 
    -- dann alle Anzeigen als "Gratis" behandeln
    -- "doppelten" Anzeigen vermeiden
    
    SELECT 9 AS temp_kat, kategorie, datum, id 
      FROM test_daten
     WHERE kategorie IN (1,3,9)
       AND datum <= CURRENT_DATE
       AND id NOT IN (SELECT id 
                        FROM test_daten
                      WHERE kategorie = 1
                        AND datum BETWEEN CURRENT_DATE - 4 AND CURRENT_DATE
                      
                      UNION 
                      
                      SELECT  id 
                        FROM test_daten
                       WHERE kategorie = 3
                         AND datum BETWEEN CURRENT_DATE AND CURRENT_DATE
                     )
    
    -- Sortiert nach der "temporären" Kategorie und dem Datum
    ORDER BY 1, 3 DESC
    LIMIT 10;
    
    
    +----------+-----------+------------+----+
    | temp_kat | kategorie | datum      | id |
    +----------+-----------+------------+----+
    |        1 |         1 | 2010-04-12 |  5 |
    |        1 |         1 | 2010-04-11 |  4 |
    |        1 |         1 | 2010-04-10 |  3 |
    |        1 |         1 | 2010-04-09 |  2 |
    |        1 |         1 | 2010-04-08 |  1 |
    |        3 |         3 | 2010-04-12 | 11 |
    |        9 |         9 | 2010-04-12 | 17 |
    |        9 |         9 | 2010-04-11 | 16 |
    |        9 |         3 | 2010-04-11 | 10 |
    |        9 |         9 | 2010-04-10 | 15 |
    +----------+-----------+------------+----+
    10 rows in set (0.00 sec)

    Wenn zuviele "Kat. 1" Anzeigen da sind, kann es vorkommen,
    dass die Kat.3 Anzeigen nicht ausgegeben werden.
    Da sind weitere Regeln notwenig.

    Die Tücke liegt ziemlich im Detail.

    Grüße
    Thomas

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    Zitat von DanielB Beitrag anzeigen
    Es gibt Premium-Anzeigen, die für 5 Tage unter den ersten Einträgen stehen (Kategorie1)
    Dann gibt es Anzeigen zum Basis-Tarif für 1 Tag unter den ersten Einträgen (Kategory 3)
    Und dann der Rest als Gratis-Anzeigen die einfach nur nach Datum sortiert werden.
    Dafür bietet es sich an, mittels IF oder CASE ein zusätzliches Sortierkriterium zu erstellen.

    Wenn Premium und noch keine 5 Tage alt bzw. wenn Basis und noch keine 3 Tage alt, dann Sortierwert = 1, sonst Sortierwert = 0.
    Zuerst danach absteigend sortieren, und dann nach Datum als zweitem Kriterium.

    Einen Kommentar schreiben:


  • DanielB
    antwortet
    Zitat von ChrisB Beitrag anzeigen
    Kategorie1 soll 5 Tage (von $today)
    Kategorie3 soll 1 Tag (von $today)
    ... unter den ersten Einträgen im Array so weit wie möglich vorne stehen.

    Das ist weniger ein Puzzle, mehr ein Rätsel.
    Und um das aufzulösen, liefere bitte mal ein verständliche Beschreibung.
    OK - Du hast Recht - sorry

    Es wird ja so sein, dass die Datumssortierung an sich zu dem Problem führen kann, dass die 3 Blöcke gemischt werden?

    Viellleich wäre es einfacher wenn ich das ganze etwas mehr mit Leben fülle:
    Vergessen wir die Butter und Lebensmittel und denken es wären Anzeigen:

    Es gibt Premium-Anzeigen, die für 5 Tage unter den ersten Einträgen stehen (Kategorie1)
    Dann gibt es Anzeigen zum Basis-Tarif für 1 Tag unter den ersten Einträgen (Kategory 3)
    Und dann der Rest als Gratis-Anzeigen die einfach nur nach Datum sortiert werden.

    Hoffe man kann nachvollziehen was ich brauche.

    Einen Kommentar schreiben:


  • ChrisB
    antwortet
    Zitat von DanielB Beitrag anzeigen
    Frage 1)
    Ich will jetzt zusätzlich noch nach Datum sortieren....
    Ja dann mach das doch - was hält dich auf?

    Frage 2)
    Es ist wichtig, dass die Kategorien (1-3) nach Blöcken im Array sortiert stehen und dabei nach Datum in den Blöcken sortiert sind.
    Keine neue Frage, sondern Bestandteil von 1)
    (Beides keine Fragen.)

    Frage 3)
    Kategorie1 soll 5 Tage (von $today)
    Kategorie3 soll 1 Tag (von $today)
    ... unter den ersten Einträgen im Array so weit wie möglich vorne stehen.
    Keine Ahnung, was du hier wissen willst.

    Frage 4)
    Auch keine Frage erkennbar.


    Wäre echt super, wenn hier jemand weiß, wie ich das Puzzel am besten baue.
    Das ist weniger ein Puzzle, mehr ein Rätsel.
    Und um das aufzulösen, liefere bitte mal ein verständliche Beschreibung.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Dein Beispiel sieht formatiert so aus und hat einen Fehler. Zwei mal "WHERE" geht an der Stelle nicht.

    Code:
    SELECT *, DATE_FORMAT(datum,'%d-%m-%Y') AS datumfeld 
      FROM tabelle 
     WHERE datum >= 04.10.2010 
     WHERE art='butter' 
       AND land='deutschland' 
       AND beschreibung LIKE "%marke%" 
     ORDER BY FIND_IN_SET(typ,'NULL,kategorie1,ketegorie3,kategorie2') DESC 
     LIMIT 1,8
    Ich vermute mal, da kann auch ein "AND" hin.

    Lösung zu Frage 1) "..zusätzlich nach Datum sortieren..."

    Code:
    SELECT *, DATE_FORMAT(datum,'%d-%m-%Y') AS datumfeld 
      FROM tabelle 
     WHERE datum >= 04.10.2010 
       AND art='butter' 
       AND land='deutschland' 
       AND beschreibung LIKE "%marke%" 
     ORDER BY 
      datum, FIND_IN_SET(typ,'NULL,kategorie1,ketegorie3,kategorie2') DESC 
     LIMIT 1,8
    Meintest Du das so..(Datum vorne), oder so... Datum hinten

    Code:
     ...
     ORDER BY 
    FIND_IN_SET(typ,'NULL,kategorie1,ketegorie3,kategorie2') DESC,   datum 
    LIMIT 1,8
    Grüße
    Thomas

    Einen Kommentar schreiben:


  • DanielB
    antwortet
    Zitat von thomas_w Beitrag anzeigen
    kannst du mal den SQL-Befehl ausgeben, nachdem er zusammen gebaut ist, also den Inhalt von $query? Dann läßt sich die Abfrage besser analysieren.

    PHP-Code:
    echo $query
    PHP-Code:
    SELECT *, DATE_FORMAT(datum,'%d-%m-%Y') AS datumfeld FROM tabelle WHERE datum >= 04.10.2010 WHERE art='butter' AND land='deutschland' AND beschreibung LIKE "%marke%" ORDER BY FIND_IN_SET(typ,'NULL,kategorie1,ketegorie3,kategorie2'DESC LIMIT 1,
    Hoffe du kannst mir helfen

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    kannst du mal den SQL-Befehl ausgeben, nachdem er zusammen gebaut ist, also den Inhalt von $query? Dann läßt sich die Abfrage besser analysieren.

    PHP-Code:
    echo $query
    Grüße
    Thomas

    Einen Kommentar schreiben:

Lädt...
X