Nowe i ulepszone (wersja 3 jak) wykorzystujące zmienne i używające zasadniczo tej samej sztuczki z tutaj :
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
Dla przykładowych danych, które podałeś, daje to coś takiego:
+--------------+-----------+
| 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 |
+--------------+-----------+
Powinno to działać dla dowolnego wyniku rozmiaru; po prostu zmień warunek (y_of_birth = 2000
), aby być w dowolnym stanie. Zaktualizowałem do MySQL 5.6, aby to przetestować (w rzeczywistości okazało się, że to mała różnica).
Podstawowa sztuczka polega na utworzeniu dwuwierszowej tabeli ze statycznymi wartościami (w tym przypadku 1
i 0
) za pomocą UNION
a następnie LEFT JOIN
że do rzeczywistych wyników kilka razy, aby wypełnić do potęgi 2. Oznacza to,że obliczyliśmyliczbękażdego wiersza w wyniku (o nazwie row_num
), abyśmy mogli poprawnie sformułować warunek złączenia. W końcu daje to zduplikowany wiersz co tyle wierszy; ostatni bit to zmiana tego, co wybieramy na tych duplikatach (za pomocą IF
s) sprawdzając, czy jesteśmy na prawdziwym czy fałszywym (1
lub 0
) wiersz.
Powinno to uniemożliwić graczom z tej samej drużyny przebywanie obok siebie, chyba że jest to niemożliwe, ponieważ jedna drużyna ma zbyt wielu graczy; zobacz powyższy link, aby uzyskać więcej informacji o tym, jak to zrobić. Podstawową ideą jest zamawianie według klubu, a następnie naprzemienne wybieranie z pierwszej i drugiej połowy tej listy.
Ostatnią sztuczką było ustalenie, ile i gdzie połączyć się w rzędach manekinów. Po wypróbowaniu kilku rzeczy zdałem sobie sprawę, że jest to w rzeczywistości bardzo proste:po prostu łącz z każdym wierszem, aż osiągniemy pożądaną liczbę fikcyjnych wierszy (@extra
). Jednak spowoduje to umieszczenie wszystkich fałszywych wierszy na górze wyników; aby je bardziej rozłożyć (nie idealnie rozłożone, ale bardziej rozłożone), oblicz, jak często musimy je dodać (FLOOR(@count / @extra)
), a następnie umieść jeden co tyle wierszy (pierwsza część ON
warunek), dopóki nie zostanie dodana wystarczająca ilość (druga część).