sql >> Databasteknik >  >> RDS >> Mysql

SQL - skriv ut många ord mellan varje kolumn med många villkor

Ny och förbättrad (version 3 hur) med variabler och använder i princip samma trick från här :

SELECT
  IF(is_real, '**ANY WORD**', full_name) AS full_name,
  IF(is_real, '', club_name) AS club_name
FROM
  (
    SELECT
      full_name,
      club_name,
      (@row_num2:= @row_num2 + 1) AS row_num
    FROM
      (
        SELECT p3.*
        FROM
          (
        SELECT
          p2.*,
          (@row_num := @row_num + 1) AS row_num
        FROM
          (
            SELECT *
            FROM players AS p1
            WHERE y_of_birth = 2000
          ) AS p2
        CROSS JOIN
          (
            SELECT
              @row_num := 0,
              @count := (SELECT COUNT(*) FROM players WHERE y_of_birth = 2000)
          ) AS vars
        ORDER BY club_name
      ) AS p3
    ORDER BY row_num % FLOOR(@row_num / 2), row_num
  ) AS p4
CROSS JOIN
  (
    SELECT
      @row_num2 := -1,
      @extra := GREATEST(2, POW(2, CEIL(LOG2(@count)))) - @count) AS vars
  ) AS data
LEFT JOIN
  (
    (SELECT 1 AS is_real)
    UNION ALL
    (SELECT 0 AS is_real)
  ) AS filler
ON
  MOD(row_num, FLOOR(@count / @extra)) = 0 AND
  row_num / FLOOR(@count / @extra) < @extra
ORDER BY row_num, is_real

För exemplet data du gav, producerar detta något som:

+--------------+-----------+
| full_name    | club_name |
+--------------+-----------+
| Ahmed Sayed  | El Ahly   |
| **ANY WORD** |           |
| Mohamed gad  | Ismaily   |
| **ANY WORD** |           |
| omar galal   | Cocorico  |
| **ANY WORD** |           |
| Kareem Gaber | El Ahly   |
| Kamal saber  | wadi dgla |
+--------------+-----------+

Detta bör fungera för alla storlekar resultat; ändra bara villkoret (y_of_birth = 2000 ) för att vara vilket skick du vill. Jag uppgraderade till MySQL 5.6 för att testa detta (det visade sig faktiskt göra en liten skillnad).

Det grundläggande tricket är att skapa en tvåradstabell med statiska värden (i detta fall 1 och 0 ) med en UNION och sedan LEFT JOIN att in i de faktiska resultaten ett antal gånger för att fylla upp till en potens av 2. Det betyder att vi har beräknat numret för varje rad i resultatet (kallas row_num ) så att vi kan formulera kopplingsvillkoret korrekt. I slutändan ger detta en dubblettrad var så många rader; den sista biten är att ändra vad vi väljer på dessa dubbletter (med IF s) genom att kontrollera om vi är på en äkta eller falsk (1 eller 0 ) rad.

Detta bör förhindra att spelare från samma lag står bredvid varandra om inte detta är omöjligt eftersom ett lag har för många spelare; se länken ovan för mer om hur du gör det. Grundidén är att beställa efter klubb och sedan växla mellan första halvan och andra halvan av listan.

Det sista tricket var att ta reda på hur många och var man skulle gå med i dummyraderna. Efter att ha provat flera saker insåg jag att detta faktiskt är väldigt enkelt:gå bara med varje rad tills vi har nått önskat antal dummy-rader (@extra ). Men det kommer att packa alla dummy-rader överst i resultaten; för att sprida ut dem mer (inte perfekt utspridda, utan mer utspridda), beräkna hur ofta vi behöver lägga till en (FLOOR(@count / @extra) ) och sätt sedan en var så många rader (den första delen av ON). skick) tills tillräckligt många har lagts till (den andra delen).



  1. tolka användarskrivna fulltextsökningsfrågor till WHERE-satsen i MySQL med PHP

  2. Hur Div() fungerar i PostgreSQL

  3. MySQL DATETIME - Ändra endast datumet

  4. 2 främmande nycklar som refererar till samma primära nyckel i MySQL