在MySQL中将记录展平为列
我想将表中的多条记录作为结果集中的不同列展平。例如:在MySQL中将记录展平为列,mysql,sql,Mysql,Sql,我想将表中的多条记录作为结果集中的不同列展平。例如: select product_id, url from images where product_id = 1; +-------------+-------------------------------+ | product_id | url | +-------------+-------------------------------+ | 1 | http:
select product_id, url from images where product_id = 1;
+-------------+-------------------------------+
| product_id | url |
+-------------+-------------------------------+
| 1 | http://example.com/images/abc |
| 1 | http://example.com/images/def |
| 1 | http://example.com/images/ghi |
+-------------+-------------------------------+
我希望结果集有三列,如下所示:
+-------------+---------------------------------+-------------------------------+-------------------------------+
| product_id | Image 1 | Image 2 | Image 3 |
+-------------+---------------------------------+-------------------------------+-------------------------------+
| 1 | http://example.com/images/abc | http://example.com/images/def | http://example.com/images/ghi |
+-------------+---------------------------------+-------------------------------+-------------------------------+
在这种情况下,我们没有三行,我希望最后一列为null。例如—
select product_id, url from images where product_id = 2;
+-------------+-------------------------------+
| product_id | url |
+-------------+-------------------------------+
| 2 | http://example.com/images/abc |
| 2 | http://example.com/images/def |
+-------------+-------------------------------+
然后,输出应为:
+-------------+---------------------------------+-------------------------------+-------------------------------+
| product_id | Image 1 | Image 2 | Image 3 |
+-------------+---------------------------------+-------------------------------+-------------------------------+
| 2 | http://example.com/images/abc | http://example.com/images/def | NULL |
+-------------+---------------------------------+-------------------------------+-------------------------------+
如果超过3行,我们可以安全地忽略超过3行
任何帮助都将不胜感激。相关子查询可能是最简单的方法:
select p.product_id,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 0
) as url1,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 1
) as url2,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 2
) as url3
from products p;
这假设您有一个名为products的表。如果没有,您可以始终使用从图像p中选择不同的产品id
这还假设图像中有图像id列。如果没有,您可以使用order by url
如果不想使用products表,可以执行以下操作:
select p.product_id,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 0
) as url1,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 1
) as url2,
(select i.url
from images i
where i.product_id = p.product_id
order by i.image_id
limit 1 offset 2
) as url3
from (select distinct product_id from images) p;
这将按产品id对url组中的记录进行排序。然后获得每个组id的前三条记录
select product_id,
max(case when rank=1 then url end) as url_1,
max(case when rank=2 then url end) as url_2,
max(case when rank=3 then url end) as url_3
from (
select a.product_id,
a.url,
count(b.product_id)+1 as rank
from images a
left join images b
on a.product_id=b.product_id and a.url>b.url
group by a.product_id,
a.url
) t
group by product_id
order by product_id;
MySQL非常擅长使本应简单的事情变得更加困难。这仍然是一个轴心,但在MySQL中它与T-SQL有点不同 编辑:我们可以使用动态变量@rn复制行号功能以保存行号,@pid保存前一行的产品号,然后将其交叉应用回images表。我使用rn值关联产品ID记录 Product_ID 3表明它将忽略返回的任何超过3个的图像URL MySQL 5.6架构设置: 问题1: :
MySQL的哪个版本?MySQL版本:5.6请您详细说明您在回答中提到的没有products表的部分。交换限制和偏移量。我无法让它们以偏移量x限制x的形式在SQLFIDLE中工作,但它确实可以与限制x偏移量x一起工作。
CREATE TABLE images (product_id int, url varchar(50) ) ;
INSERT INTO images
SELECT 1,'http://example.com/images/abc' UNION ALL
SELECT 1,'http://example.com/images/def' UNION ALL
SELECT 1,'http://example.com/images/ghi' UNION ALL
SELECT 2,'http://example.com/images/abc' UNION ALL
SELECT 2,'http://example.com/images/def' UNION ALL
SELECT 3,'http://example.com/images/qrz' UNION ALL
SELECT 3,'http://example.com/images/rzq' UNION ALL
SELECT 3,'http://example.com/images/zqr' UNION ALL
SELECT 3,'http://example.com/images/qqq' UNION ALL
SELECT 3,'http://example.com/images/rrr' UNION ALL
SELECT 3,'http://example.com/images/zzz'
;
SELECT s1.product_ID
, max( CASE WHEN s1.rn = 1 THEN s1.url END ) AS Image1
, max( CASE WHEN s1.rn = 2 THEN s1.url END ) AS Image2
, max( CASE WHEN s1.rn = 3 THEN s1.url END ) AS Image3
FROM (
SELECT t1.product_ID, t1.url
, @rn:=CASE WHEN @pid=product_ID THEN @rn+1 ELSE 1 END AS rn
, @pid:=product_ID AS pid
FROM images t1, ( SELECT @rn:=0,@pid:='' ) AS t
ORDER BY t1.product_ID
) s1
GROUP BY s1.product_ID
ORDER BY s1.product_ID
| product_ID | Image1 | Image2 | Image3 |
|------------|-------------------------------|-------------------------------|-------------------------------|
| 1 | http://example.com/images/abc | http://example.com/images/def | http://example.com/images/ghi |
| 2 | http://example.com/images/abc | http://example.com/images/def | (null) |
| 3 | http://example.com/images/rrr | http://example.com/images/qqq | http://example.com/images/zqr |