Nuovo e migliorato (versione 3 come) utilizzando variabili e utilizzando sostanzialmente lo stesso trucco da qui :
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
Per i dati di esempio che hai fornito, questo produce qualcosa del tipo:
+--------------+-----------+
| 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 |
+--------------+-----------+
Questo dovrebbe funzionare per qualsiasi risultato di dimensione; cambia semplicemente la condizione (y_of_birth = 2000
) per essere qualunque condizione tu voglia. Ho eseguito l'aggiornamento a MySQL 5.6 per testarlo (in realtà si è scoperto che faceva una piccola differenza).
Il trucco di base è creare una tabella a due righe con valori statici (in questo caso, 1
e 0
) utilizzando un UNION
e poi LEFT JOIN
che nei risultati effettivi un certo numero di volte per riempire fino a una potenza di 2. Ciò significa che abbiamo calcolato il numero di ogni riga nel risultato (chiamato row_num
) in modo da poter formulare correttamente la condizione di unione. Alla fine, questo produce una riga duplicata ogni tante righe; l'ultimo bit è cambiare ciò che selezioniamo su quei duplicati (usando IF
s) verificando se siamo su un sito reale o falso (1
o 0
) riga.
Ciò dovrebbe impedire che i giocatori della stessa squadra siano uno accanto all'altro a meno che ciò non sia impossibile perché una squadra ha troppi giocatori; vedere il collegamento sopra per ulteriori informazioni su come farlo. L'idea di base è quella di ordinare per mazza e poi alternare il prelievo dalla prima metà e dalla seconda metà di quell'elenco.
L'ultimo trucco è stato capire quanti e dove unire nelle file fittizie. Dopo aver provato diverse cose, mi sono reso conto che in realtà è molto semplice:basta unirci a ogni riga finché non abbiamo raggiunto il numero desiderato di righe fittizie (@extra
). Tuttavia, ciò impacchetterà tutte le righe fittizie nella parte superiore dei risultati; per distribuirli di più (non perfettamente distesi, ma più distesi), calcola la frequenza con cui dobbiamo aggiungerne uno (FLOOR(@count / @extra)
) e poi metti una ogni tante righe (la prima parte di ON
condizione) fino a che non ne sia stata aggiunta una quantità sufficiente (la seconda parte).