mysql:从另一个表中选择行作为列

时间:2015-07-20 10:28:44

标签: mysql

在mysql中以某种方式可以从第二个表(内容)中获取行显示为第一个(库存)中的列吗?

由于第二个表中的ID不是唯一的,JOIN会产生重复,但我需要将第一个表的所有元素作为单个行。

这些是表格: http://sqlfiddle.com/#!9/6da06/1

需要这样的结果:

id name      location   desc1  level1  desc2  level2  desc3  level3
1  test      somewhere  abc    20      def    50      ghi    30
2  anything  something  rfg    20      lzb    80      null   null
3  xxyzyzy   dffsdfd    atc    20      null   null    null   null

表结构的更改是不可能的,所以有什么方法mysql可以做到这一点。表格内容中可以出现多少重复的ID没有限制...需要每行库存,没有重复。如果sql可以做某事,或者在PHP中合并这些数组会非常酷吗?

2 个答案:

答案 0 :(得分:0)

如果与每个content行关联的inventory行数量有限,则可以使用以下查询:

SELECT i.`id`, i.`name`, i.`location`,
       MAX(CASE WHEN c.rn = 1 THEN c.`desc` END) AS desc1,
       MAX(CASE WHEN c.rn = 1 THEN c.`level` END) AS level1,
       MAX(CASE WHEN c.rn = 2 THEN c.`desc` END) AS desc2,
       MAX(CASE WHEN c.rn = 2 THEN c.`level` END) AS level2,
       MAX(CASE WHEN c.rn = 3 THEN c.`desc` END) AS desc3,
       MAX(CASE WHEN c.rn = 3 THEN c.`level` END) AS level3
FROM inventory AS i
LEFT JOIN ( 
  SELECT `id`, `desc`, `level`,
         @row_number := IF (@id <> id, 
                           IF (@id := id, 1, 1),
                           IF (@id := id, @row_number+1, @row_number+1)) AS rn
  FROM content 
  CROSS JOIN (SELECT @row_number := 0, @id := 0) AS vars
  ORDER BY `id`, `desc` 
) AS c ON i.`id` = c.`id`
GROUP BY i.id, i.name, i.location  

以上使用变量将增量数分配给属于同一content切片的id行。然后使用条件聚合来调整相关的content行。

Demo here

答案 1 :(得分:0)

嘿试试这个用于表的转轴,它将生成你的结果,列名作为你的等级的值,在'描述'和'等级'这里你不需要检测等级的长度,即level1,level2。这可能对您有所帮助SQLFIDDLE

set @sql = null;
set @sql1 = null;

select
  group_concat(distinct
    concat(
      'max(case when c.level = ''',
      c.level,
      ''' then c.level end) AS ',
      concat('level','_',level)
    )
  ) into @sql
  from inventory i left join content c on i.id = c.id;

  select
  group_concat(distinct
    concat(
      'max(case when c.level = ''',
      c.level,
      ''' then c.desc end) AS ',
      concat('desc','_',level)
    )
  ) into @sql1
  from inventory i left join content c on i.id = c.id;

set @sql = concat('select i.Name,', @sql, ',',@sql1,' from inventory i left join content c on i.id = c.id group by i.id
');

prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;