Ново и подобрено (версия 3 как), използвайки променливи и използвайки основно същия трик от тук :
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
За примерните данни, които сте дали, това произвежда нещо като:
+--------------+-----------+
| 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 |
+--------------+-----------+
Това трябва да работи за резултат от всякакъв размер; просто променете условието (y_of_birth = 2000
) да бъде каквото си пожелаете. Надстроих до MySQL 5.6, за да тествам това (всъщност се оказа, че има малка разлика).
Основният трик е да създадете двуредова таблица със статични стойности (в този случай 1
и 0
) с помощта на UNION
и след това LEFT JOIN
това в действителните резултати няколко пъти, за да се попълни до степен 2. Това означава, че сме изчислили броя на всеки ред в резултата (наречен row_num
), за да можем да формулираме правилно условието за присъединяване. В крайна сметка това създава дублиран ред на всеки толкова редове; последният бит е да променим това, което избираме за тези дубликати (използвайки IF
s) като проверим дали сме на истински или фалшив (1
или 0
) ред.
Това трябва да попречи на играчи от един и същи отбор да бъдат един до друг, освен ако това е невъзможно, защото един отбор има твърде много играчи; вижте връзката по-горе за повече информация как да направите това. Основната идея е да поръчате по клуб и след това да редувате бране от първата половина и втората половина на този списък.
Последният трик беше да разберете колко и къде да се присъедините към фиктивните редове. След като опитах няколко неща, разбрах, че това всъщност е много лесно:просто се присъединете към всеки ред, докато достигнем желания брой фиктивни редове (@extra
). Това обаче ще опакова всички фиктивни редове в горната част на резултатите; за да ги разпределите повече (не идеално разпръснати, но по-разпръснати), изчислете колко често трябва да добавяме един (FLOOR(@count / @extra)
) и след това поставете по един на всеки толкова редове (първата част от ON
условие), докато не се добави достатъчно (втората част).