首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL -将多行放入一行

SQL -将多行放入一行
EN

Stack Overflow用户
提问于 2013-01-06 22:57:03
回答 2查看 114关注 0票数 0

在尝试从MYSQL DB创建数据馈送时,我遇到了以下情况。在实际情况中涉及到更多的表,但我想保持这个简短,并集中在手头的问题上。我有两个带有中间表(products_options_values_to_products_options).的表(products_options_values,products_options)(对表格的格式表示歉意,但我认为您可以区分每个字段的值。)

代码语言:javascript
运行
复制
TABLE:  products_options_values<br>
products_options_values_id | products_options_values_name <br>
28 9-11<br>
52 Black<br>
53 In-Line<br>

TABLE: products_options_values_to_products_options<br>
products_options_values_to_products_options_id | products_options_id | products_options_values_id<br> 
    31  2   28<br>
    56  1   52<br>
    57  3   53<br>

TABLE: products_options<br>
products_options_id | products_options_name <br>
    1           Color<br>
    2           Size<br>
    3           Style<br>

我正在尝试编写一条具有以下结果的SQL语句:来自不同表的关于某个产品的字段,字段名为products_options_name,并且在同一行中具有相应的products_options_values_name和相应值。例如:

代码语言:javascript
运行
复制
Product_ID   Product_Name       MPN Price   Color   Size    Style
00001   Acme Rollerskates   A99 99.99   Black   9-11    In-Line 

关于如何在MYSQL中实现这一结果,有什么帮助吗?感谢您的考虑和努力。标记

EN

回答 2

Stack Overflow用户

发布于 2013-01-06 23:17:41

要将您提供的表转换成这种格式,您基本上是在执行透视,但是MySQL没有透视函数。因此,您需要使用带有CASE语句的聚合函数来复制它:

代码语言:javascript
运行
复制
select 
  max(case when po.products_options_name = 'Color' 
      then pov.products_options_values_name else null end) Color,
  max(case when po.products_options_name = 'Size' 
      then pov.products_options_values_name else null end) Size,
  max(case when po.products_options_name = 'Style' 
      then pov.products_options_values_name else null end) Style
from products_options po
left join products_options_values_to_products_options pv
  on po.products_options_id = pv.products_options_id
left join products_options_values pov
  on pv.products_options_values_id = pov.products_options_values_id

请参阅SQL Fiddle with Demo

结果是:

代码语言:javascript
运行
复制
| COLOR | SIZE |   STYLE |
--------------------------
| Black | 9-11 | In-Line |

看起来您仍然需要加入包含产品详细信息的表中,如product_idproduct_nameprice等。

我不能从您提供的表结构中看出您连接这些数据的位置,但是查询应该是这样的:

代码语言:javascript
运行
复制
select p.product_id,
  p.product_name,
  p.MPN,
  p.price,
  max(case when po.products_options_name = 'Color' 
      then pov.products_options_values_name else null end) Color,
  max(case when po.products_options_name = 'Size' 
      then pov.products_options_values_name else null end) Size,
  max(case when po.products_options_name = 'Style' 
      then pov.products_options_values_name else null end) Style
from products p  --- add join to the main products table
left join products_options po
  on p.product_id = po.products_options_id
left join products_options_values_to_products_options pv
  on po.products_options_id = pv.products_options_id
left join products_options_values pov
  on pv.products_options_values_id = pov.products_options_values_id
group by p.product_id, p.product_name, p.MPN, p.price
票数 0
EN

Stack Overflow用户

发布于 2013-01-06 23:27:34

我不确定你是否听说过Magento,但这与他们的EAV设置类似。基本上,如果您希望将行转换为列,则必须为每个行值重复一次与字段值表的左连接。我将在下面做一个简化的版本。

代码语言:javascript
运行
复制
products table:
[id, product_name]
1, product 1
2, product 2
3, product 3

product_fields table:
[id, product_id, field_name, field_value]
1, 1, color, red
2, 2, color, blue
3, 3, color, black
4, 1, size, XL
5, 2, size, XL
6, 3, size, XL

SELECT 
    p.product_name,
    table1.field_value AS color,
    table2.field_value AS size
FROM
    products AS p LEFT JOIN product_fields AS table1 ON
        p.id = table1.product_id AND
        table1.field_name='color'
    LEFT JOIN product_fields AS table2 ON
        p.id = table2.product_id AND
        table1.field_name='size'

通常,在join子句中将使用id而不是字段名,但您应该明白这一点。此外,sql server还提供了一个透视函数,它可能会执行您所需的操作。我不相信有Mysql的等价物,但你可以研究一下。

编辑:bluefeet的答案模拟了sql server的PIVOT函数。在2005年之前,sql server也是这样做的。他的答案是在我回答的时候贴出来的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14183311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档