3

ここは少し複雑です。結果を列名として使用する方法を検討してきましたが、可能だと思われますが、私が見つけたすべての例は非常に単純なテーブル設計を使用しています。

私が持っているのは3つのテーブルです。

「order」テーブルがあり、「order_extras」を持つことができます。「extras」テーブルには、追加の名前と価格が格納され、「order_extras」には基本的に、主キー、注文 ID、および追加 ID が含まれます。

これを大まかにグラフで表すと、次のようになります。ここに画像の説明を入力

これを例として、「extras」テーブルに 3 つの追加アイテムが入力されていると仮定します。この段階では、名前と価格は関係ありません。

私がやりたいことは、すべての注文を取得することですが、追加の各アイテムの名前には追加の列があります。アイテムが購入されている場合 (order_extras テーブルにリンクされている場合)、価格が表示されます。それ以外の場合は、空/null になります。

これは可能ですか?ピボット テーブルを調べてきましたが、この種の情報は少し不安定なようです。情報や提案をいただければ幸いです。

サンプルデータ

エクストラ:

+----+------------------+--------+
| id |       name       | price  |
+----+------------------+--------+
|  1 | Insurance        | 59.95  |
|  2 | Lifetime Updates | 79.95  |
|  3 | Phone Support    | 124.95 |
+----+------------------+--------+

注文:

+----+------------+
| id |  customer  |
+----+------------+
|  1 | John Smith |
|  2 | Bob Newbie |
|  3 | Bill Jobs  |
|  4 | Ray Stantz |
+----+------------+

order_extras:

+----+----------+----------+
| id | order_id | extra_id |
+----+----------+----------+
|  1 |        4 |        2 |
|  2 |        3 |        1 |
|  3 |        3 |        3 |
|  4 |        1 |        1 |
+----+----------+----------+

望ましい出力:

+----------+----------------+-----------+------------------+---------------+
| order.id | order.customer | Insurance | Lifetime Updates | Phone Support |
+----------+----------------+-----------+------------------+---------------+
|        1 | John Smith     | 59.95     | 0                | 0             |
|        2 | Bob Newbie     | 0         | 0                | 0             |
|        3 | Bill Jobs      | 59.95     | 0                | 124.95        |
|        4 | Ray Stantz     | 0         | 79.95            | 0             |
+----------+----------------+-----------+------------------+---------------+
4

2 に答える 2

2

残念ながら、MySQL にはピボット関数がありませんが、集計関数とCASE式を使用して複製できます。

の数がわかっている場合はextras、クエリをハードコーディングできます。

select o.id,
  o.customer,
  max(case when e.name = 'Insurance' then e.price else 0 end) Insurance,
  max(case when e.name = 'Lifetime Updates' then e.price else 0 end) `Lifetime Updates`,
  max(case when e.name = 'Phone Support' then e.price else 0 end) `Phone Support`
from orders o
left join order_extras oe
  on o.id = oe.order_id
left join extras e
  on oe.extra_id = e.id
group by o.id, o.customer

SQL Fiddle with Demoを参照してください。

あなたの状況では、不明な数の値があるようです。その場合は、準備済みステートメントを使用して動的 SQL を生成する必要があります。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(CASE WHEN e.name = ''',
      name,
      ''' THEN e.price else 0 END) AS `',
      name, '`'
    )
  ) INTO @sql
FROM extras;

SET @sql 
  = CONCAT('SELECT o.id,
                o.customer, ', @sql, ' 
            from orders o
            left join order_extras oe
              on o.id = oe.order_id
            left join extras e
              on oe.extra_id = e.id
            group by o.id, o.customer');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SQL Fiddle with Demoを参照してください。

これらのバージョンの両方で結果が得られます。

| ID |   CUSTOMER | INSURANCE | LIFETIME UPDATES | PHONE SUPPORT |
------------------------------------------------------------------
|  1 | John Smith |     59.95 |                0 |             0 |
|  2 | Bob Newbie |         0 |                0 |             0 |
|  3 |  Bill Jobs |     59.95 |                0 |        124.95 |
|  4 | Ray Stantz |         0 |            79.95 |             0 |
于 2013-03-21T22:06:54.217 に答える
1

これを試して 。

    select o.id , o.customer ,
    max(if(e.name = 'Insurance' , round(e.price,2), 0)) as Insurance,
    max(if(e.name = 'Lifetime Updates' , round(e.price,2), 0)) as Lifetime_Updates,
    max(if(e.name = 'Phone Support' , round(e.price,2), 0)) as Phone_Support

     from orders o
     left join order_extras oe
     on o.id = oe.order_id
    left join Extras e
    on oe.extra_id = e.id

    group by o.id, o.customer

デモはこちら

出力は次のとおりです。

   ID   CUSTOMER    INSURANCE   LIFETIME_UPDATES    PHONE_SUPPORT
    1   John Smith   59.95              0                0
    2   Bob Newbie     0                0                0
    3   Bill Jobs    59.95              0              124.95
    4   Ray Stantz     0              79.95              0
于 2013-03-21T22:06:01.857 に答える