Mysql
 sql >> Base de données >  >> RDS >> Mysql

SQL - imprime plusieurs mots entre chaque colonne avec de nombreuses conditions

Nouveau et amélioré (version 3 comment) en utilisant des variables et en utilisant essentiellement la même astuce de ici :

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

Pour l'exemple de données que vous avez donné, cela produit quelque chose comme :

+--------------+-----------+
| 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 |
+--------------+-----------+

Cela devrait fonctionner pour n'importe quel résultat de taille; changez simplement la condition (y_of_birth = 2000 ) pour être la condition que vous voulez. J'ai mis à niveau vers MySQL 5.6 pour tester cela (il s'est avéré que cela faisait une petite différence).

L'astuce de base consiste à créer un tableau à deux lignes avec des valeurs statiques (dans ce cas, 1 et 0 ) en utilisant un UNION puis LEFT JOIN cela dans les résultats réels un certain nombre de fois pour remplir jusqu'à une puissance de 2. Cela signifie que nous devons calculer le nombre de chaque ligne dans le résultat (appelé row_num ) afin que nous puissions formuler correctement la condition de jointure. En fin de compte, cela produit une ligne en double toutes les lignes ; le dernier bit est de changer ce que nous sélectionnons sur ces doublons (en utilisant IF s) en vérifiant si on est sur un vrai ou un faux (1 ou 0 ) ligne.

Cela devrait empêcher les joueurs d'une même équipe d'être côte à côte, sauf si cela est impossible car une équipe a trop de joueurs ; voir le lien ci-dessus pour en savoir plus sur la façon de le faire. L'idée de base est de commander par club puis d'alterner la cueillette dans la première moitié et la seconde moitié de cette liste.

La dernière astuce consistait à déterminer combien et où se joindre aux rangées factices. Après avoir essayé plusieurs choses, j'ai réalisé que c'était en fait très simple :il suffit de joindre chaque ligne jusqu'à ce que nous ayons atteint le nombre souhaité de lignes factices (@extra ). Cependant, cela emballera toutes les lignes factices en haut des résultats ; pour les étaler davantage (pas parfaitement étalés, mais plus étalés), calculez la fréquence à laquelle nous devons en ajouter un (FLOOR(@count / @extra) ) puis mettez une toutes ces lignes (la première partie du ON condition) jusqu'à ce que suffisamment aient été ajoutés (la deuxième partie).