sql >> データベース >  >> RDS >> Mysql

SQL-多くの条件ですべての列の間に多くの単語を出力します

    変数を使用し、こちら と基本的に同じトリックを使用して新しく改善された(バージョン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 )あなたが望むどんな状態でもあります。これをテストするためにMySQL5.6にアップグレードしました(実際には小さな違いがありました)。

    基本的なトリックは、静的な値(この場合は1)を使用して2行のテーブルを作成することです。 および0UNIONを使用する 次にLEFT JOIN これを実際の結果に数回入れて、2の累乗にします。これは、結果の各行の数を計算したことを意味します(row_numと呼ばれます)。 )結合条件を適切に定式化できるようにします。結局、これは非常に多くの行ごとに重複する行を生成します。最後のビットは、それらの複製で選択するものを変更することです(IFを使用) s)本物か偽物かを確認する(1 または0 )行。

    これにより、1つのチームのプレーヤーが多すぎるためにこれが不可能でない限り、同じチームのプレーヤーが隣り合うことを防ぐことができます。その方法の詳細については、上記のリンクを参照してください。基本的な考え方は、クラブごとに注文してから、そのリストの前半と後半から交互に選択することです。

    最後の秘訣は、ダミー行の数と場所を把握することでした。いくつかのことを試した後、これは実際には非常に簡単であることに気付きました。目的のダミー行の数(@extra)に達するまで、すべての行を結合するだけです。 )。ただし、結果の上部にすべてのダミー行がパックされます。それらをさらに広げるには(完全には広げられませんが、もっと広げます)、1つ追加する必要がある頻度を計算します(FLOOR(@count / @extra) )次に、その数の行ごとに1つ配置します(ONの最初の部分) 条件)十分に追加されるまで(2番目の部分)。



    1. Symfony3データベースにユーザーロールを保存する方法

    2. SQLServerの動的ピボットテーブル

    3. codeigniterアクティブレコードはクエリを取得し、LIMIT句なしでクエリを実行します

    4. JavaScript PHP/MYSQLで削除する前に確認する