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