MySQL列名作为与连接表的多对多关系的字段名

MySQL列名作为与连接表的多对多关系的字段名,mysql,sql,many-to-many,pivot,pivot-table,Mysql,Sql,Many To Many,Pivot,Pivot Table,这里有点复杂。我一直在寻找一种将结果用作列名的方法,虽然这似乎是可能的,但我发现的所有示例都使用了非常简单的表设计 我有三张桌子 我们有一个“订单”表,然后可以有“订单附加”。“extras”表存储extras的名称和价格,“order_extras”基本上包含主键、订单id和extra id 粗略的图形表示如下: 以此为例,假设“extras”表中填充了3个额外的项目,在此阶段名称和价格是无关的 我想做的是获取所有订单,但每个额外项目的名称都有额外的列。如果物品已经购买(在order_extr

这里有点复杂。我一直在寻找一种将结果用作列名的方法,虽然这似乎是可能的,但我发现的所有示例都使用了非常简单的表设计

我有三张桌子

我们有一个“订单”表,然后可以有“订单附加”。“extras”表存储extras的名称和价格,“order_extras”基本上包含主键、订单id和extra id

粗略的图形表示如下:

以此为例,假设“extras”表中填充了3个额外的项目,在此阶段名称和价格是无关的

我想做的是获取所有订单,但每个额外项目的名称都有额外的列。如果物品已经购买(在order_extras表中链接),它将显示价格,否则它将为空/空

这可能吗?我一直在研究数据透视表,但这类信息似乎有点不可靠。任何信息或建议将不胜感激

示例数据

额外费用:

+----+------------------+--------+
| 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 |
+----+------------+
额外订购:

+----+----------+----------+
| 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             |
+----------+----------------+-----------+------------------+---------------+
试试这个

    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

不幸的是,MySQL没有pivot函数,但是可以使用带有
CASE
表达式的聚合函数来复制

如果您有已知数量的
附加项
,则可以对查询进行硬编码:

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:

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;

这两个版本都将给出以下结果:

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

你能发布一些样本数据和期望的结果吗?如果不读“问题”这个词,你可能更容易理解你在做什么据我所知,MySQL根本不支持任何类型的pivot关键字或“true”pivot。看看这篇文章。这家伙写了一篇疯狂的文章来处理这个问题:刚刚用一些我希望做的事情的例子更新了第一篇文章。希望它能有所帮助。首先,感谢第二个例子——这是正确的!我尝试通过本地数据库运行它,查询成功运行,但实际上没有返回任何内容。有点奇怪,它的工作方式显然是显示行数,但没有列出任何结果。在phpMyAdmin和mac应用程序“Sequel Pro”中都尝试过这一点。:/It's奇怪-如果我将其作为标准查询运行,它不会输出任何内容。不过谢天谢地,我还是想把它导出到CSV。使用outfile,它可以完美地工作!