sql >> Database teknologi >  >> RDS >> Mysql

SQL - udskriv mange ord mellem hver kolonne med mange betingelser

Nyt og forbedret (version 3 how) ved at bruge variabler og bruge stort set det samme trick fra her :

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
 

For de eksempeldata, du gav, producerer dette noget som:

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

Dette burde virke for ethvert størrelsesresultat; bare skift betingelsen (y_of_birth = 2000 ) for at være den betingelse, du ønsker. Jeg opgraderede til MySQL 5.6 for at teste dette (det viste sig faktisk at gøre en lille forskel).

Det grundlæggende trick er at oprette en tabel med to rækker med statiske værdier (i dette tilfælde 1 og 0 ) ved hjælp af en UNION og derefter LEFT JOIN at ind i de faktiske resultater et antal gange for at fylde op til en potens af 2. Det betyder, at vi har beregnet antallet af hver række i resultatet (kaldet row_num ), så vi kan formulere sammenføjningsbetingelsen korrekt. I sidste ende producerer dette en dublet række hver så mange rækker; den sidste bit er at ændre, hvad vi vælger på disse dubletter (ved hjælp af IF s) ved at tjekke, om vi er på en ægte eller falsk (1 eller 0 ) række.

Dette bør forhindre, at spillere fra samme hold er ved siden af ​​hinanden, medmindre dette er umuligt, fordi et hold har for mange spillere; se linket ovenfor for mere om, hvordan du gør det. Den grundlæggende idé er at bestille efter klub og derefter skiftevis udvælgelse fra første halvdel og anden halvdel af listen.

Det sidste trick var at finde ud af, hvor mange og hvor man skulle deltage i dummy-rækkerne. Efter at have prøvet flere ting, indså jeg, at dette faktisk er meget nemt:bare deltag med hver række, indtil vi har nået det ønskede antal dummy-rækker (@extra ). Det vil dog pakke alle dummy-rækkerne øverst i resultaterne; for at sprede dem mere (ikke perfekt spredt ud, men mere spredt ud), beregn hvor ofte vi skal tilføje en (FLOOR(@count / @extra) ) og sæt derefter en for hver så mange rækker (den første del af ON). tilstand), indtil der er tilføjet nok (anden del).



  1. angivelse af klassesti for selvstændig jython

  2. Vis alle nullbare kolonner i en SQL Server-database

  3. Standard rækkefølge i SELECT-forespørgsel - SQL Server 2008 vs SQL 2012

  4. Hvordan opdaterer man mysql med python, hvor felter og indgange er fra en ordbog?