自我加入SQL查询

时间:2011-03-31 16:42:06

标签: mysql sql join self

前几天我要求解决我需要解决的SQL查询,我的数据如下:

meta_id post_id     meta_key    meta_value
269     4   _apais               USA
270     4   _aciudad             New york
271     4   _aservicio           Pleasure

...
272     43  _apais               USA
273     43  _aciudad             Chicago
274     43  _aservicio           Fun
...
275     44  _apais               USA
276     44  _aciudad             Miami
277     44  _aservicio           Night Life

278     45  _apais               USA
279     45  _aciudad             Miami
280     45  _aservicio           Sports

我需要做的是显示所有与Country with City和Service匹配的寄存器。或者按国家/地区(和_aservicio As服务)订购所有_aciudad寄存器,例如:

meta_id     post_id     meta_key    meta_value  meta_key    meta_value  meta_key  meta_value
270         7           _apais          USA     _aciudad    New York   _aservicio Pleasure
261         13          _apais          USA     _aciudad    Chicago    _aservicio Fun
276         4           _apais          USA     _aciudad    Miami      _aservicio Sports

@Ravi Gummadi给了我一个看起来像这样的解决方案:

SELECT t1.meta_id, 
           t1.post_id, 
           t1.meta_key, 
           t1.meta_value, 
           t2.meta_key, 
           t2.meta_value 
    FROM th_postmeta t1, th_postmeta t2  
    WHERE t1.post_id = t2.post_id 
    AND t1.meta_key = '_apais'
    AND t2.meta_key = '_aciudad'
    ORDER BY t1.meta_key

该查询返回:

meta_id     post_id     meta_key    meta_value  meta_key    meta_value
270         7           _apais          USA     _aciudad    New York
261         13          _apais          USA     _aciudad    Chicago
276         4           _apais          USA     _aciudad    Miami
279         10          _apais          USA     _aciudad    Miami

我如何才能只显示meta_value值中没有重复的记录(仅适用于_aciudad和_aservicio,_apais可以重复)?

非常感谢你们!

2 个答案:

答案 0 :(得分:1)

如果您不需要meta_id和post_id,则只需删除文本t1.post_id,t1.meta_id,然后将SELECT更改为SELECT DISTINCT

如果你需要post_id,你需要告诉我们如何决定保留哪一行 - meta_id = 276或meta_id = 279 - 正如Lamak在上面的评论中所指出的那样。 / p>

编辑1:

如果你想在查询中保留meta_id和post_id,但是你不关心meta_id和post_id中保留哪些值,那么你可以这样做:

SELECT
    MAX(t1.meta_id), 
    MAX(t1.post_id), 
    t1.meta_key, 
    t1.meta_value, 
    t2.meta_key, 
    t2.meta_value 
FROM th_postmeta t1, th_postmeta t2  
WHERE t1.post_id = t2.post_id 
AND t1.meta_key = '_apais'
AND t2.meta_key = '_aciudad'
GROUP BY t1.meta_key, t1.meta_value, t2.meta_key, t2.meta_value
ORDER BY t1.meta_key

请注意,您可能会使用此方法将meta_ids和post_ids从不同的记录“混合”在一起,因为不能保证具有最高meta_id的记录也具有最高的post_id,反之亦然。 / p>

如果您不需要meta_id或post_id,只需要meta_keys和meta_values,则可以执行以下操作:

SELECT DISTINCT
    t1.meta_key, 
    t1.meta_value, 
    t2.meta_key, 
    t2.meta_value 
FROM th_postmeta t1, th_postmeta t2  
WHERE t1.post_id = t2.post_id 
AND t1.meta_key = '_apais'
AND t2.meta_key = '_aciudad'
ORDER BY t1.meta_key

如果这些方法都不适合您,那么您需要为我们提供一些额外的标准,以便我们知道如何为您完善解决方案。

答案 1 :(得分:1)

因此,您将获得具有相同meta_value的多行。您想丢弃其中一些行,即使它们对其他字段有不同的值?在SQL Server中,您可能会执行以下操作:

SELECT
    ..., x = ROW_NUMBER() OVER(PARTITION BY meta_value ORDER BY meta_id )
WHERE
   x <= 1

这引入了另一个计算列(x),每个meta_value(分区依据)上重新开始的每一行(order by)的数字越来越多。 order by子句定义哪些是最重要的保留/丢弃,而where是每个保留的数量。

meta_id     post_id     meta_key    meta_value  meta_key    meta_value   x
261         13          _apais          USA     _aciudad    Chicago      1
270         7           _apais          USA     _aciudad    New York     2
276         4           _apais          USA     _aciudad    Miami        3
279         10          _apais          USA     _aciudad    Miami        4
280         10          _apais          ABC     _aciudad    Miami        1
281         10          _apais          ABC     _aciudad    Miami        2

我意识到你把它标记为MySql。我并不真正使用MySQL,并希望这只是为您提供了一些谷歌新功能的线索。也许:

ROW_NUMBER() in MySQL