5

私はこのようなテーブルを持っています:

ID | FIELD_NAME   | VALUE
23 |  sign_up     |  yes
23 |  first_name  |  Fred
23 |  street      |  Barber Lane
24 |  sign_up     |  no
24 |  first_name  |  Steve
24 |  street      |  Camaro St.
25 |  sign_up     |  yes
25 |  first_name  |  Larry
25 |  street      |  Huckleberry Ave

一意のIDと値を名前付き列として選択するクエリを実行して、次のように表示したいと思います。

ID   |   SIGN_UP   | FIRST_NAME  |  STREET           |
23   |     yes     |    Fred     |  Barber Lane      |
24   |     no      |    Steve    |  Camaro St.       |
25   |     yes     |    Larry    |  Huckleberry Ave. |

どんな助けでも大歓迎です!!

4

5 に答える 5

5

グループ化と条件付き集計を使用してピボットを試すこともできます。

SELECT
  ID,
  MAX(CASE FIELD_NAME WHEN 'sign_up'    THEN VALUE END) AS SIGN_UP,
  MAX(CASE FIELD_NAME WHEN 'first_name' THEN VALUE END) AS FIRST_NAME,
  MAX(CASE FIELD_NAME WHEN 'street'     THEN VALUE END) AS STREET
FROM atable
GROUP BY
  ID
;
于 2012-07-10T19:31:15.947 に答える
5

この簡単なソリューションを使用できます。

SELECT DISTINCT
    a.id,
    b.value AS SIGN_UP,
    c.value AS FIRST_NAME,
    d.value AS STREET
FROM tbl a
LEFT JOIN tbl b ON a.id = b.id AND b.field_name = 'sign_up'
LEFT JOIN tbl c ON a.id = c.id AND c.field_name = 'first_name'
LEFT JOIN tbl d ON a.id = d.id AND d.field_name = 'street'

id に欠落フィールドLEFT JOINがあるかどうかわからないため、安全のために joins を作成しました。その場合、派生列のように表示されます。NULL


SQL フィドルのデモ

于 2012-07-10T18:10:02.260 に答える
2

私による別の回答からの適応:

SELECT ids.ID AS ID,
       sign_up.VALUE AS SIGN_UP,
       first_name.VALUE AS FIRST_NAME,
       street.VALUE AS STREET
FROM (SELECT DISTINCT ID FROM tableName) AS ids
     LEFT JOIN tableName AS sign_up
            ON (sign_up.ID = ids.ID AND
                sign_up.FIELD_NAME = 'sign_up')
     LEFT JOIN tableName AS first_name
            ON (first_name.ID = ids.ID AND
                first_name.FIELD_NAME = 'first_name')
     LEFT JOIN tableName AS street
            ON (street.ID = ids.ID AND
                street.FIELD_NAME = 'street')

NULL左結合により、行全体が省略されるのではなく、欠損値がセルになることが保証されます。アプリケーションでそれが重要かどうかはわかりません。そうでない場合は、内部結合を使用して、特にサブクエリを削除して、すべての一意の ID を選択できます。これを導き出した元の回答を参照してください。

于 2012-07-10T19:17:21.660 に答える
0

1 つのアプローチは、相関サブクエリを使用して各フィールド値を列として返すことです。

SELECT t.id
     , (SELECT f1.value FROM mytable f1 
         WHERE f1.id = t.id AND f1.field_name = 'sign_up' 
         ORDER BY f1.value LIMIT 1
       ) AS SIGN_UP
     , (SELECT f2.value FROM mytable f2 
         WHERE f2.id = t.id AND f2.field_name = 'first_name' 
         ORDER BY f2.value LIMIT 1
       ) AS FIRST_NAME
     , (SELECT f3.value FROM mytable f3 
         WHERE f3.id = t.id AND f3.field_name = 'street'
         ORDER BY f3.value LIMIT 1
       ) AS STREET
  FROM (SELECT s.id
          FROM mytable s
         GROUP BY s.id
         ORDER BY s.id
       ) t

これが唯一の方法ではありませんが、特に、正確に 4 つの列が返されること、およびそれらが特定の順序で返されることを懸念している場合は、実行可能なアプローチです。

このアプローチは、特定の ID に対して特定の field_name が「欠落」している場合に機能することに注意してください (値の代わりに NULL が返されます)。特定の ID に対して同じ field_name が複数回出現する場合にも機能します。(このクエリは、そのうちの 1 つだけを返し、もう 1 つを無視します。)

これと同じ結果セットは、次のように記述されたクエリでも取得できます。

SELECT t.id          AS ID
     , f1.sign_up    AS SIGN_UP
     , f2.first_name AS FIRST_NAME
     , f3.street     AS STREET       
  FROM (SELECT s.id
          FROM mytable s
         GROUP BY s.id
         ORDER BY s.id
       ) t
   LEFT      
   JOIN (SELECT s1.id
              , MIN(s1.value) AS sign_up
           FROM mytable s1
          WHERE s1.field_name = 'sign_up'
            AND s1.value IS NOT NULL 
          GROUP BY s1.id
        ) f1
     ON f1.id = t.id   
   LEFT
   JOIN (SELECT s2.id
              , MIN(s2.value) AS first_name
           FROM mytable s2
          WHERE s2.field_name = 'first_name'
            AND s2.value IS NOT NULL
          GROUP BY s2.id
        ) f2
     ON f2.id = t.id
   LEFT
   JOIN (SELECT s3.id
              , MIN(s3.value) AS street
           FROM mytable s3
          WHERE s3.field_name = 'street'
            AND s3.value IS NOT NULL
          GROUP BY s3.id
        ) f3
     ON f3.id = t.id

他のクエリではfield_name、特定の ID に対して a が「欠落」している場合、特定の ID に重複がある場合field_name、またはテーブルに関係のない追加の field_name 値がある場合に、目的の動作が得られることを確認してください。

于 2012-07-10T18:11:04.477 に答える
0

MySQL にピボット/アンピボット機能があるかどうかはわかりません。これを試して:

SELECT a.ID, 
       c.FIELD_NAME AS SIGN_UP,
       a.FIELD_NAME AS FIRST_NAME,
       b.FIELD_NAME AS STREET

  FROM <YOUR-TABLE> a LEFT JOIN <YOUR-TABLE> b
        ON a.ID = b.ID 
     AND a.FIELD_NAME = 'first_name'
     AND b.FIELD_NAME = 'street' LEFT JOIN <YOUR-TABLE> c
        ON c.ID = a.ID
     AND c.FIELD_NAME = 'sign_up'
于 2012-07-10T18:06:32.653 に答える