如何使用mysql值作为列名来减少行数?

时间:2015-05-23 20:18:34

标签: mysql

SELECT uo.id as visited_object, uo.id, uo.parent_object, object_username,
       object_title, object_type, lat, lng, uop.propertyName,
       uop.propertyContent,
       (SELECT avg(child_value) FROM `uf_object_childs` uoc
        LEFT JOIN uf_objects uo ON uoc.object_id=uo.id
        WHERE uoc.child_type='rev_rating') as object_rating
FROM `uf_objects` uo
LEFT JOIN uf_object_properties uop ON uo.id=uop.objectId
WHERE uo.object_type='page'

上面的查询返回以下内容

enter image description here

如何更改它以便它只返回一行,其中propertyName值将用作列名,而propertyContent用作它们各自的值。

这意味着我只得到一行,其中包含名为cover_photo,city和address的三个额外列,其值分别为http:// ....,纽约和林肯广场,纽约......

任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

如果你知道你想要哪些属性列,你就可以这样做,假设每个属性只存在一个'对象'。

基本上,您按对象ID进行分组,并聚合属性值。我正在使用max,但您也可以使用min。它只是一种聚合属性并选择其中一个值的方法。它是哪一个,取决于使用IF函数的属性名称(您也可以使用CASE)。

SELECT 
  uo.id as visited_object, uo.id, uo.parent_object, object_username,
  object_title, object_type, lat, lng, uop.propertyName,
  uop.propertyContent,
       (SELECT avg(child_value) FROM `uf_object_childs` uoc
        LEFT JOIN uf_objects uo ON uoc.object_id=uo.id
        WHERE uoc.child_type='rev_rating') as object_rating
  MAX(IF(uop.propertyName = 'cover_photo', uop.PROPERYVALUE, null)) AS cover_photo,
  MAX(IF(uop.propertyName = 'city', uop.PROPERYVALUE, null)) AS city,
  MAX(IF(uop.propertyName = 'address', uop.PROPERYVALUE, null)) AS address
FROM `uf_objects` uo
LEFT JOIN uf_object_properties uop ON uo.id=uop.objectId
WHERE uo.object_type='page'
GROUP BY 
  uo.id

但请注意,如果我可以这么说,你必须这样做的原因,次优查询,是因为你的数据模型也不是很好。对象数据(id,user,parent,object_title等)以冗余方式存储,这通常是一个不好的标志。

通常,您要为'cover_photo'这样的属性创建实际列,因此您不必复制object_title和其他字段。

或者,您可以创建一个object_properties的单独表,其中包含标签和每个对象的值。如果您不知道属性是什么,这将特别有用,但如果您这样做,上面的建议会更好。对于这样一个单独的表,您仍然需要一个查询来将数据“转移”到您要求的展平中,但至少数据本身不会被冗余存储。