MySQL列名作为与连接表的多对多关系的字段名
这里有点复杂。我一直在寻找一种将结果用作列名的方法,虽然这似乎是可能的,但我发现的所有示例都使用了非常简单的表设计 我有三张桌子 我们有一个“订单”表,然后可以有“订单附加”。“extras”表存储extras的名称和价格,“order_extras”基本上包含主键、订单id和extra id 粗略的图形表示如下: 以此为例,假设“extras”表中填充了3个额外的项目,在此阶段名称和价格是无关的 我想做的是获取所有订单,但每个额外项目的名称都有额外的列。如果物品已经购买(在order_extras表中链接),它将显示价格,否则它将为空/空 这可能吗?我一直在研究数据透视表,但这类信息似乎有点不可靠。任何信息或建议将不胜感激 示例数据 额外费用: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
+----+------------------+--------+
| 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,它可以完美地工作!