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

PHPおよびMysqlクエリ、PHPを使用して行を列に変換

    SQLクエリを使用して結果を取得することは可能ですが、それは簡単ではありません。

    ただし、そのルートに進む前に、別のアプローチを検討することをお勧めします。

    クエリは比較的小さな行のセットを返すため、代わりに結果セット全体を2次元配列としてPHPに取得できます。

    例として、かなり単純なケースを考えてみましょう。

    SELECT foo, fee, fi, fo, fum
      FROM mytable 
     ORDER BY foo
    
    foo fee fi  fo  fum
    --- --- --- --- ---
    ABC   2   3   5   7
    DEF  11  13  17  19
    

    fetchAllを実行し、2次元配列を取得してから、配列をループして、行単位ではなく列単位で値を取得することができます。 1つのオプションは、受け取った配列を次のような新しい配列に変換することです。

    bar  ABC  DEF
    ---  ---  ---
    fee    2   11
    fi     3   13
    fo     5   17
    fum    7   19
    

    変換を行う必要はありません。元の配列をウォークすることができます。ただし、変換を別のステップとして分離すると、実際にページに出力を生成するときに、コードが少し簡単になる可能性があります。 (誰かがあなたが望む配列変換を行う関数を書いたのは十分に一般的な問題のようです。それを行うPHPが組み込まれているとは思いません。

    見出し:

    array { [0]=>'bar'  [1]=>'ABC'  [2]=>'DEF' }
    

    行:

    array {
      [0]=>array { [0]=>'fee'   [1]=>'2'  [2]=>'11' }
      [1]=>array { [0]=>'fi'    [1]=>'3'  [2]=>'13' }
      [2]=>array { [0]=>'fo'    [1]=>'5'  [2]=>'17' }
      [3]=>array { [0]=>'fum'   [1]=>'7'  [2]=>'19' }
    }
    

    あなたが持っているような小さな行のセットについては、SQLではなくPHPでこれを行うことを選択します。

    しかし、あなたはSQLでそれを行う方法を尋ねました。前に言ったように、それは些細なことではありません。

    SQLでは、SELECTステートメントで返されるすべての列を定義する必要があります。ステートメントの実行時に、列の数とタイプを動的にすることはできません。

    列を定義する別のクエリ(元のクエリとは別に)を作成し、値のプレースホルダーとともに返されると予想される行を返す場合、その途中です。残っているのは、元のクエリによって返された行に対して外部結合を実行し、適切な行の列値を条件付きで返すことだけです。

    このアプローチは、特に元の行ソースがスパースであり、「欠落している」行を生成する必要がある場合に、返される必要のある事前定義された行と列のセットがある場合に機能します。 (たとえば、注文された製品の数を取得し、欠落している行がたくさんある場合、欠落している行を生成する良い方法はありません。

    例:

    SELECT r.bar
         , '' AS `ABC`
         , '' AS `DEF`
      FROM ( SELECT 'fee' AS bar
              UNION ALL SELECT 'fi'
              UNION ALL SELECT 'fo'
              UNION ALL SELECT 'fum'
           ) r
     GROUP BY r.bar
    

    戻ります:

     bar  ABC  DEF
     ---  ---  ---
     fee
     fi
     fo
     fum
    

    つまり、これですべての列が定義され、すべての行が返されます。最初の列にデータが入力されます。そのクエリにはまだGROUPBYは必要ありませんが、「実際の」ソース結果セットの行と一致したら、GROUPBYが必要になります。

    「トリック」は、ソースからの行と一致し、適切な条件に基づいて列から値を返すようになりました。

    生成するのは、基本的に次のような結果セットです。

    bar  foo  ABC  DEF
    ---  ---  ---  ---
    fee  ABC    2
    fee  DEF        11
    fi   ABC    3
    fi   DEF        13
    fo   ABC    5
    fo   DEF        15
    fum  ABC    7
    fum  DEF        17
    

    次に、結果セットからfoo列を削除し、barでGROUPBYを実行して、行を「折りたたむ」ことにします。 。 NULL値で行う処理を利用して、集計関数(MAXまたはSUM)を使用して、次のような結果を生成します。

    bar  foo  ABC  DEF
    ---  ---  ---  ---
    fee         2   11
    fi          3   13
    fo          5   15
    fum         7   17
    

    このかなり扱いにくいSQLの使用:

    SELECT r.bar
         , MAX(CASE WHEN t.foo = 'ABC' THEN CASE r.bar 
             WHEN 'fee' THEN t.fee 
             WHEN 'fi'  THEN t.fi
             WHEN 'fo'  THEN t.fo
             WHEN 'fum' THEN t.fum
           END END) AS 'ABC'
         , MAX(CASE WHEN t.foo = 'DEF' THEN CASE r.bar 
             WHEN 'fee' THEN t.fee 
             WHEN 'fi'  THEN t.fi
             WHEN 'fo'  THEN t.fo
             WHEN 'fum' THEN t.fum
           END END) AS 'DEF'
      FROM ( SELECT 'foo' AS col
              UNION ALL SELECT 'fee'
              UNION ALL SELECT 'fi'
              UNION ALL SELECT 'fo'
              UNION ALL SELECT 'fum'
           ) r
     CROSS
      JOIN mysource t
     GROUP BY r.bar
    

    mysourceに注意してください 上記のクエリでは、インラインビューに置き換えることができ、必要な行を返す適切なクエリの周りに親をラップします。

    rとしてエイリアスされたインラインビュー 返したい行を返すためのソースです。

    SELECTリストの式は、各行の各列に適切な値を選択するために、条件付きテストを実行しています。

    CASEステートメントの規則的なパターンを考えると、クエリの生成に役立つSQLを使用することは可能ですが、それは別のステップとして実行する必要があります。そのSQLからの出力は、必要な実際のクエリの作成に役立てることができます。

    あなたの場合、そのworkdate は列ヘッダーに使用するものです。これは動的に生成する必要がある可能性があります。 (その2番目の列の「曜日」列を元のソースクエリから削除し、それを外部クエリに移動することができます。

    workdateがわからなかった場合 クエリを実行する前の見出しの値、次にTEMPORARY TABLEを作成し、元のクエリの結果を入力してから、一時テーブルにクエリを実行して、workdateを取得します。 ヘッダー、および行を生成するための「最初の列」。次に、一時テーブルに対して実際のクエリを実行します。

    繰り返しになりますが、SQLで実行するよりも、PHPで元のクエリの結果の変換/ピボットを実行する方がよいと思います。



    1. null値を含む配列でPDOを実行する

    2. #1054on句エラーの不明な列

    3. JPA、EclipseLink、大文字と小文字を区別するmysqlの問題

    4. 古いテーブルから別のテーブルへのデータの移動PHPMYSQL