SQL子查询将字段值作为结果的字段名称

时间:2015-05-27 23:27:20

标签: mysql sql

我有这个表,我想要实现的是将detail_key列的某些行作为列名,将detail_value作为实际行。

Table places

detail_key | detail_value
--------------------------
location   | Athens
country    | Greece
longtitude | 12,3333
weather    | good

我已尝试过下面的查询,但每次仅适用于1个字段。

SELECT detail_value AS location FROM places  WHERE detail_key= 'location';

我想要实现的结果如下:

location   | country | longtitude
-----------|---------|-------------
 Athens    |Greece   |12,3333

1 个答案:

答案 0 :(得分:2)

这听起来像一张十字架。

MySQL不包含交叉表的内置函数,但您可以手动构建交叉表查询"。

重要提示:您必须拥有一个密钥才能对数据进行分组。我假设您有place_id列:

select max(case detail_key when 'location' then detail_value end) as location
     , max(case detail_key when 'country' then detail_value end) as country
     -- and so on
from places
-- add any WHERE conditions here
group by place_id

希望这有帮助。

修改

您的评论让我重新思考您的问题,我找到了解决方案here。以下是您需要做的事情:

  1. 创建一个变量,其中包含您要应用的表达式以获取所需内容
  2. 创建有效的SQL查询
  3. 在您的查询准备就绪时使用预准备语句。
  4. 我为你创建了一个小SQL fiddle,看看如何解决这个问题,现在是:

    SQL Fiddle

    MySQL 5.6架构设置

    create table places(
      id int unsigned not null auto_increment primary key,
      place_id int,
      detail_key varchar(50),
      detail_value varchar(50)
    );
    
    insert into places (place_id, detail_key, detail_value) values
    (1, 'location','Athens'),(1,'country','Greece'),(1,'longitude','12.3333'),(1,'weather','good');
    

    查询1

    set @sql = null
    

    Results :(无结果)

    查询2

    select group_concat(distinct
                        concat(
                          "max(case detail_key when '",
                          detail_key,
                          "' then detail_value end) as `",
                          detail_key,
                          "`"
                        )
           )
    into @sql
    from places
    

    Results :(无结果)

    查询3

    set @sql = concat("select place_id, ", @sql, " from places group by place_id")
    

    Results :(无结果)

    查询4

    prepare stmt from @sql
    

    Results :(无结果)

    查询5

    execute stmt
    

    <强> Results

    | place_id | location | country | longitude | weather |
    |----------|----------|---------|-----------|---------|
    |        1 |   Athens |  Greece |   12.3333 |    good |
    

    最终编辑

    如果你以某种方式创建了上面的表格,其数据只对应一个地方(即没有place_id并且所有细节都来自一个地方),你可以这样做:

    select max(case detail_key when 'location' then detail_value end) as location
         , max(case detail_key when 'country' then detail_value end) as country
         -- and so on
    from places
    -- add any WHERE conditions here
    group by null;