SQL - печатать много слов между каждым столбцом со многими условиями

Сначала у меня есть неизменяемые значения:

4   8   16   32   64   128   256

и у меня есть одна таблица примерно так:

+----+------+---------------------+-------------+
| id |   full_name  |  club_name  |  y_of_birth |
+----+------+---------------------+-------------+
| 1  | Ahmed Sayed  |   El Ahly   |    2000     |
+----+------+---------------------+-------------+
| 2  | Kareem Gaber |   El Ahly   |    2000     |
+----+------+---------------------+-------------+
| 3  | Maher Zein   |   El Ahly   |    2003     |
+----+------+---------------------+-------------+
| 4  | Mohab Saeed  |   El Ahly   |    2003     |
+----+------+---------------------+-------------+
| 5  | Kamal saber  |   wadi dgla |    2000     |
+----+------+---------------------+-------------+
| 6  | gamel kamel  |   el-nasr   |    2002     |
+----+------+---------------------+-------------+
| 7  | omar galal   |   Cocorico  |    2000     |
+----+------+---------------------+-------------+
| 8  | Kamal saber  |   Cocorico  |    2004     |
+----+------+---------------------+-------------+
| 9  | Mohamed gad  |   Ismaily   |    2000     |  
+----+------+---------------------+-------------+
| 10 | ehab zeyad   |   Ismaily   |    2005     |
+----+------+---------------------+-------------+
| 11 | moaz maged   |   Smouha    |    2001     |
+----+------+---------------------+-------------+
| 12 | mazen mahmod |   elmasry   |    2006     |
+----+------+---------------------+-------------+
| 13 | ahmed shawky |   Petroget  |    2002     |
+----+------+---------------------+-------------+
| 14 | shaker ali   |   Petroget  |    2007     |
+----+------+---------------------+-------------+

и я попытался отфильтровать данные из базы данных с запросом

select full_name,club_name from players where y_of_birth=2000

и результат 5 должен быть примерно таким:

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

Хорошо условие:

если результат больше 4 > 4 и меньше 8 <= 8 поместите результат в 8, в нашем случае результат 5 это означает, что 8 - 5 = 3 означает повторение этого слова 3 раза, результат должен быть примерно таким:

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

Примечание:, пожалуйста, не смежно между **ANY WORD** и выше:

+------+-------+
| **ANY WORD** |
+--------------+
| **ANY WORD** |
+--------------+

ИЛИ

нет рядом с club_name до примера:

+------+-------+
|    El Ahly   |
+--------------+
|    El Ahly   |
+--------------+

Обновлено:

еще раз примеры

на основе этих чисел

4 8 16 32 64 128 256

и условие :

  • если результат запроса <= 4 и > 2 означает (4 - the number of query result)

пример:, если результат запроса 3, поэтому 4 - 3 = 1, поэтому 1 - это число **ANY WORD**, поэтому желаемый результат будет таким:

+--------------+-------------+
|   full_name  |  club_name  |
+--------------+-------------+
| Ahmed Sayed  |  El Ahly    |
+----+------+--+-------------+
| **ANY WORD** |             |
+--------------+-------------+
| Kareem Gaber |  El Ahly    |
+------+-------+-------------+
| Kamal saber  |  wadi dgla  |
+--------------+-------------+
  1. другой пример с 8 если результат запроса <= 8 и > 4 означает (8 - the number of query result)

например: результат запроса равен 5, поэтому 8 - 5 = 3, поэтому 3 представляет собой число **ANY WORD**, поэтому желаемый результат будет таким, что

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

и т.д. с 4 и 16 и 32 и 64..etc до 256.

Любая помощь будет высоко оценена.

Ответ 1

Новый и улучшенный (вариант 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), пока (вторая часть).

Ответ 2

Следующая процедура вернет 4 столбца. Необходимо отобразить первый и второй столбцы. Третий столбец - это только rownum, который следует игнорировать. Если четвертый столбец не пуст, отобразите его в следующей строке, иначе не отобразите его.

DELIMITER //
create procedure test()
BEGIN
declare N int;
declare X int;
select count(*) from players where y_of_birth=2000 into N;
set X = power(2,ceil(log2(N))) -N;
SELECT full_name, club_name, @row := @row + 1 AS row, 
case when (@row<= X) 
then 'any word' else '' end r
FROM players, (SELECT @row:=0) z
where y_of_birth=2000;
END //
DELIMITER 

call test;