Mysql,根据另一个单元格的内容选择一个单元格的值

时间:2012-08-17 18:40:16

标签: mysql

我当前的代码

SELECT post_id, ( 3959 * ACOS( COS( RADIANS( 34.09 ) ) * COS( RADIANS( lat ) ) * COS( RADIANS( lng ) - RADIANS( -117.55 ) ) + SIN( RADIANS( 34.09 ) ) * SIN( RADIANS( lat ) ) ) ) AS distance FROM wp_postmeta WHERE `meta_key` LIKE '%location_l%' HAVING distance < 2500 ORDER BY distance LIMIT 0 , 20

以下是两个示例数据行(meta_key不总是long或lat):

post_id = 123  
meta_key = location_longitude  
meta_value = -119.890000  

post_id = 123  
meta_key = location_latitude   
meta_value = 42.170000

如何修改我的查询以将原始查询中的'lat'和'lng'替换为上面列出的meta_value的内容?像这样的东西?

select meta_value where meta_key = location_latitude

4 个答案:

答案 0 :(得分:1)

如果您GROUP BY post_id,您应该能够使用MAX()聚合代替lat,lng,围绕CASE语句来确定当前行是纬度还是经度。其他的将是NULL,因此被聚合消除。

我认为这应该有效,所以你不需要任何子选择。

SELECT
   post_id, 
   ( 3959 * ACOS( COS( RADIANS( 34.09 ) ) * COS( RADIANS( MAX(CASE WHEN meta_key='location_latitude' THEN meta_value ELSE NULL END) ) ) * COS( RADIANS( MAX(CASE WHEN meta_key='location_longitude' THEN meta_value ELSE NULL END) ) - RADIANS( -117.55 ) ) + SIN( RADIANS( 34.09 ) ) * SIN( RADIANS( MAX(CASE WHEN meta_key='location_latitude' THEN meta_value ELSE NULL END) ) ) ) ) AS distance 
FROM wp_postmeta 
WHERE `meta_key` IN ('location_latitude','location_longitude')
GROUP BY post_id
HAVING distance < 2500 
ORDER BY distance 
LIMIT 0 , 20

这里的移动部件是:

MAX(CASE WHEN meta_key='location_latitude' THEN meta_value ELSE NULL END)

这转换为:如果此行的meta_key'location_latitude',则返回meta_value,否则返回NULL。我们期望由于post_id(lat,lng)返回了两行,因此上面返回的MAX()值始终为非空值 - 来自{{1的正确纬度或经度值}}

答案 1 :(得分:1)

一种方法是使用内联视图替换查询中对表的引用(即FROM wp_postmeta),如下所示:

FROM
( SELECT plat.post_id
       , plat.meta_value AS lat
       , plng.meta_value AS lng
    FROM wp_postmeta plat
    JOIN wp_postmeta plng
      ON plat.post_id = plng.post_id
         AND plat.meta_key = 'location_latitude'
         AND plng.meta_ley = 'location_longitude'
) wpm

(注意:这假设每个post_id只有一行用于感兴趣的两个meta_key值...)

这使用“内联视图”将每个post_id的纬度和经度值组合成一行。 (您可以只运行内联视图的查询以确认它返回您期望的结果。)在更新版本的MySQL(版本&gt; = 5.0)中,我们可以使用内联视图代替表引用。

答案 2 :(得分:1)

您需要将表连接到自身(这在具有EAV结构的数据库中很常见):

SELECT
    post_id,
    distance
FROM
  ( SELECT 
        lng.post_id, 
        ( 3959 * ACOS( COS( RADIANS( 34.09 ) ) 
                     * COS( RADIANS( lat.meta_value ) ) 
                     * COS( RADIANS( lng.meta_value ) 
                          - RADIANS( -117.55 ) ) 
                     + SIN( RADIANS( 34.09 ) ) 
                     * SIN( RADIANS( lat.meta_value ) ) 
                     ) 
        ) AS distance 
    FROM wp_postmeta AS lng
      JOIN wp_postmeta AS lat
        ON lat.post_id = lng.post_id
    WHERE lng.meta_key = 'location_longitude'
      AND lat.meta_key = 'location_latitude'
  ) AS tmp
WHERE distance < 2500 
ORDER BY distance 
  LIMIT 0 , 20 ;

答案 3 :(得分:0)

SELECT a.post_id, 
  ( 3959 * ACOS( COS( RADIANS( 34.09 ) ) * COS( RADIANS( lat.meta_value  ) ) * COS( RADIANS( lng.meta_value  ) - RADIANS( -117.55 ) ) + SIN( RADIANS( 34.09 ) ) * SIN( RADIANS( lat.meta_value  ) ) ) ) AS distance 
FROM wp_postmeta lat, wp_postmeta lng
WHERE lat.post_id = lng.postID
AND lat.meta_key = 'location_latitude'
AND lng.meta_key = 'location_longitude'
HAVING distance < 2500 
ORDER BY distance LIMIT 0 , 20