2010-08-04 91 views
1

我有一個子選擇在一個查詢,看起來像這樣:如何在不增加返回行數的情況下修改此查詢?

left outer join 
    (select distinct ID from OTHER_TABLE) as MYJOIN 
on BASE_OBJECT.ID = MYJOIN.ID 

這是非常簡單的。通過MYJOIN.ID在相關行中是否爲空來檢查查詢的主對象與OTHER_TABLE表示的對象之間是否存在某種關係。

但是現在需求已經發生了一些變化。 OTHER_TABLE中的另一行可以具有1或0的值,並且查詢需要知道1值的主要關係之間是否存在關係,以及它是否存在0值。最明顯的解決方案是將:

left outer join 
    (select distinct ID, TYPE_VALUE from OTHER_TABLE) as MYJOIN 
on BASE_OBJECT.ID = MYJOIN.ID 

但是,因爲如果0型和1型對象都存在相同的ID,這將增加通過查詢,這ISN返回的行數,這將是錯誤的可以接受。因此,我需要的是某種子查詢,它將爲每個不同的ID返回1行,並帶有「1類型存在」列和「0類型存在」列。我不知道如何在SQL中進行編碼。

例如,下面的表中,

ID | TYPE_VALUE 
_________________ 
1 | 1 
3 | 0 
3 | 1 
4 | 0 

我想看到設置這樣的結果:

ID | HAS_TYPE_0 | HAS_TYPE_1 
______________________________ 
1 | 0   | 1 
3 | 1   | 1 
4 | 1   | 0 

任何人都知道我怎麼能建立一個查詢做到這一點?希望至少有一些醜陋的黑客?

回答

3

在一般情況下,你可以使用EXISTS:

SELECT DISTINCT ID, 
    CASE WHEN EXISTS (
      SELECT * FROM Table1 y 
      WHERE y.TYPE_VALUE = 0 AND ID = x.ID) 
     THEN 1 
     ELSE 0 END AS HAS_TYPE_0, 
    CASE WHEN EXISTS (
      SELECT * FROM Table1 y 
      WHERE y.TYPE_VALUE = 1 AND ID = x.ID) 
     THEN 1 
     ELSE 0 END AS HAS_TYPE_1 
FROM Table1 x; 

如果你有一個非常大的數字表中的元素,這將不會進行如此之大 - 這些嵌套子查詢的往往是一個吻當涉及到表演的時候,他會死。

針對您的特殊情況下,你也可以使用GROUP BY和MAX()和MIN(),以加快速度:

SELECT 
    ID, 
    CASE WHEN MIN(TYPE_VALUE) = 0 THEN '1' ELSE 0 END AS HAS_TYPE_0, 
    CASE WHEN MAX(TYPE_VALUE) = 1 THEN '1' ELSE 0 END AS HAS_TYPE_1 
FROM Table1 
GROUP BY ID; 
+0

謝謝! GROUP BY運作良好。是的,這可能是一個包含數十或數十萬個元素的非常大的數據集。 – 2010-08-04 21:59:57

2

代替select distinct ID, TYPE_VALUE from OTHER_TABLE 使用

select ID, 
MAX(CASE WHEN TYPE_VALUE =0 THEN 1 END) as has_type_0, 
MAX(CASE WHEN TYPE_VALUE =1 THEN 1 END) as has_type_1 
from OTHER_TABLE 
GROUP BY ID; 

你可以做同樣使用PIVOT操作者...

相關問題