2013-04-03 50 views
4

假設我們有如下表稱爲mealsSQL得到的記錄與同列A,但不同硼

 
| meal | stars | 
----------------- 
| steak | 1 | 
| steak | 2 | 
| fish | 4 | 
| fish | 4 | 
| salad | 5 | 

我怎樣才能用同一餐記錄,但不同的星星?我需要那些只有不同星星的唱片。

結果上面的表格應該如下:

 
| meal | stars | 
----------------- 
| steak | 1 | 
| steak | 2 | 

我試過下面的查詢:

SELECT DISTINCT t1.* 
FROM meals t1 
INNER JOIN meals t2 ON t1.meal = t2.meal 
AND t1.stars <> t2.stars; 

卻消耗了太多的時間和記憶的一些明顯的量。

我的表的實際尺寸是:

 
SELECT pg_size_pretty(pg_relation_size('table_name')); 
pg_size_pretty 
---------------- 
2295 MB 

所以,我需要拿出別的東西,我要求你的幫助!

回答

7
SELECT a.* 
FROM meals a 
     INNER JOIN 
     (
      SELECT meal 
      FROM meals 
      GROUP BY meal 
      HAVING COUNT(DISTINCT stars) > 1 
     ) b ON a.meal = b.meal 

輸出

╔═══════╦═══════╗ 
║ MEAL ║ STARS ║ 
╠═══════╬═══════╣ 
║ steak ║  1 ║ 
║ steak ║  2 ║ 
╚═══════╩═══════╝ 
1
SELECT meal,stars FROM meals 
GROUP BY meal,stars 
HAVING count(*)=1 and meal in (
    SELECT meal FROM meals 
    GROUP BY meal 
    HAVING count(*)>1) 
+0

無論你和@ J-w ^解決方案是非常好的,但第二個是速度稍快,所以我拿起它。 – melekes

0

應該是最快的方法:

SELECT m.* 
FROM meals m 
WHERE EXISTS (
    SELECT 1 FROM meals x WHERE x.meal = m.meal AND x.stars <> m.stars 
    ) 

「獲取所有的行,其中至少有一個其他餐,存在相同的名稱,但不同的星星。」

假設NULL值不會發生。

->SQLfiddle

0

一種簡單快捷的方式來達到同樣的效果

SELECT 
    m.* 
FROM  
    meals m 
    JOIN meals m2 ON (m2.meal = m.meal AND m2.stars<>m.stars)