转换查询以处理键值列

时间:2012-08-26 23:22:02

标签: php mysql sql

我需要帮助更新此查询:

$query = sprintf(
   "SELECT 
        lat, 
        lng, 
        ( 
            3959 * acos( cos( radians('%s') ) * 
                         cos( radians( lat ) ) * 
                         cos( radians( lng ) - radians('%s') ) + 
                         sin( radians('%s') ) * 
                         sin( radians( lat ) ) 
                       ) 
        ) AS distance 
    FROM 
        markers 
    HAVING 
        distance < '%s' 
    ORDER BY 
        distance LIMIT 0 , 20"

使用如下表结构:

lat        | lng
23.0324234 | -103.0324234

对于我可以从表中的键值列结构中获取shipping_latshipping_long的查询,如下所示:

meta_key      | meta_value
shipping_lat  | 23.0324234
shipping_long | -103.0324234

1 个答案:

答案 0 :(得分:1)

使用以下作为您加入主查询(或类似)的子查询?

SELECT t1.meta_value AS lat, t2.meta_value AS lng
FROM   meta_table t1 JOIN meta_table t2
WHERE  t1.meta_key = 'shipping_lat'
   AND t2.meta_key = 'shipping_long'

那是:

SELECT 
    lat, 
    lng, 
    ( 
        3959 * acos( cos( radians('%s') ) * 
                     cos( radians( lat ) ) * 
                     cos( radians( lng ) - radians('%s') ) + 
                     sin( radians('%s') ) * 
                     sin( radians( lat ) ) 
                   ) 
    ) AS distance 
FROM 
    markers JOIN (
      SELECT t1.meta_value AS lat, t2.meta_value AS lng
      FROM   meta_table t1 JOIN meta_table t2
      WHERE  t1.meta_key = 'shipping_lat'
         AND t2.meta_key = 'shipping_long'
    ) AS t
HAVING 
    distance < '%s' 
ORDER BY 
    distance LIMIT 0 , 20

可以通过将meta_table直接加入markers两次(在相关的meta_key上)然后直接引用meta_value而不是{{1}来避免子查询}}和lat,但我认为上面的内容会更易读,也更容易理解。但是,为了完整性:

lng