MySQL 8如何从多子查询派生字段实现属性行转列查询
MySQL 8 行转列查询产品属性解决方案
方案1:CASE + 聚合函数 + GROUP BY(推荐)
你之前的写法缺少聚合函数处理NULL值,同一个productid下,非目标属性对应的CASE返回值都是NULL,用MAX()/MIN()可以直接忽略NULL拿到有效值,再配合GROUP BY productid就能合并为一行:
SELECT pa.productid, MAX(CASE WHEN pa.attribute_name = 'Width' THEN pa.attribute_value END) AS att1, MAX(CASE WHEN pa.attribute_name = 'Weight' THEN pa.attribute_value END) AS att2 -- 要新增更多属性直接加新的CASE行即可 FROM product_attributes pa -- 兼容你原有的分类筛选逻辑,关联products表 JOIN products p ON pa.productid = p.productid WHERE p.catid = '12345' GROUP BY pa.productid;
如果需要筛选单个产品,把WHERE条件改成pa.productid = '1'即可。
扩展说明:
如果你的产品同一个属性可能有多个值,需要返回所有结果的话,可以用MySQL 8的GROUP_CONCAT()函数代替MAX,拼接多个值返回。
方案2:多子查询JOIN(符合你原有写法的扩展)
如果要沿用你之前子查询JOIN的写法,新增属性只要多LEFT JOIN对应属性的子查询即可:
SELECT t1.productid, t1.att1, t2.att2 FROM (SELECT productid, attribute_value AS att1 FROM product_attributes WHERE attribute_name = 'Width') t1 -- 新增Weight属性的子查询关联 LEFT JOIN (SELECT productid, attribute_value AS att2 FROM product_attributes WHERE attribute_name = 'Weight') t2 ON t1.productid = t2.productid -- 兼容原有的分类筛选 JOIN products p ON t1.productid = p.productid WHERE p.catid = '12345';
注意:
这里用LEFT JOIN而不是INNER JOIN,是为了避免某个产品没有Width属性时,连Weight属性的结果也被过滤掉。如果要求必须同时有所有指定属性才返回,改成INNER JOIN即可。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

