sql >> Databáze >  >> RDS >> Mysql

SQL - tisk mnoha slov mezi každý sloupec s mnoha podmínkami

Nové a vylepšené (jak verze 3) pomocí proměnných a pomocí v podstatě stejného triku z zde :

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

Pro ukázková data, která jste uvedli, to vytvoří něco jako:

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

To by mělo fungovat pro výsledek jakékoli velikosti; stačí změnit podmínku (y_of_birth = 2000 ), aby byla podmínka, kterou chcete. Upgradoval jsem na MySQL 5.6, abych to otestoval (ve skutečnosti se ukázalo, že je to malý rozdíl).

Základním trikem je vytvořit dvouřádkovou tabulku se statickými hodnotami (v tomto případě 1 a 0 ) pomocí UNION a poté LEFT JOIN že do skutečných výsledků se několikrát zaplní až mocnina 2. To znamená, že jsme vypočítali počet každého řádku ve výsledku (tzv. row_num ), abychom mohli správně formulovat podmínku spojení. Nakonec to vytvoří duplicitní řádek každých tolik řádků; poslední bit je změnit to, co vybereme na těchto duplikátech (pomocí IF s) kontrolou, zda jsme na skutečné nebo falešné (1 nebo 0 ) řádek.

To by mělo zabránit tomu, aby hráči ze stejného týmu byli vedle sebe, pokud to není nemožné, protože jeden tým má příliš mnoho hráčů; viz výše uvedený odkaz pro více informací o tom, jak to udělat. Základní myšlenkou je objednat podle klubu a poté střídavě vybírat z první a druhé poloviny tohoto seznamu.

Posledním trikem bylo přijít na to, kolik a kam se zapojit do řad figurín. Po vyzkoušení několika věcí jsem si uvědomil, že je to vlastně velmi snadné:stačí se spojit s každým řádkem, dokud nedosáhneme požadovaného počtu falešných řádků (@extra ). To však zaplní všechny falešné řádky v horní části výsledků; chcete-li je více rozložit (ne dokonale rozprostřené, ale více rozprostřené), spočítejte, jak často je potřeba přidat jeden (FLOOR(@count / @extra) ) a poté vložte jeden na každý tolik řádků (první část ON podmínka), dokud nebude přidán dostatek (druhá část).



  1. Online vs offline zálohování

  2. Jedinečná otázka citlivosti varchar na velká a malá písmena SQL

  3. org.hibernate.HibernateException:Databáze nevrátila žádnou nativně generovanou hodnotu identity

  4. MySQL - UPDATE dotaz založený na SELECT dotazu