2012-01-27 46 views
0

是否有更好的查詢來解決此問題?使用AND和OR更高性能的Oracle SQL動態查詢

1汽車有許多類型。

我想是這樣的:(PS這是不正確的,我知道)

select * from car join type on car.id = type.id_car 
where type = 'SUV' 
and type = '4x4' 
and (type = 'blue' or type = 'red') 
and type = 'US' 
and (type = 'Manual' or type = 'Automatic' or 'SemiAutomatic') 
and type = 'diesel' and so on. 

我的解決辦法是:

select * from car 
where numberOfANDType = (select count(1) from Type where car.id = type.id_car and type in ('suv', '4x4', 'us', 'diesel')) 
and exists (select 1 from type where car.id = type.id_car and type in ('blue', 'red')) 
and exists (select 1 from type where car.id = type.id_car and type in ('manual', 'automatic' or 'SemiAutomatic'); 

等。

ps:我知道AND使用條件的數量
ps2:這些條件是動態的。

Anywayz:我已經爲每個類型一個GROUP列,以及用於OR組中的類型,我在這個列中具有相同的值。 SUV的GROUP = 1,藍色的GROUP = 2,紅色的GROUP = 2等等。 因此,我對TYPE列和組中的計數進行查詢,以查看是否覆蓋了所有組。

Select id from car join type on .. where type in ('SUV', 'blue', 'red') group by id having count(distinct group) > 2; 

謝謝。

ps3:多虧了所有誰低估了這個問題,你是非常友善的。

+0

有你使用解釋計劃來查看這個查詢是否不好?如果我沒有弄錯,當你使用存在時,Oracle會使用你的類型FK指向汽車PK。 – 2012-01-27 13:41:39

+0

目前還不清楚你試圖達到什麼樣的目標 - 你是否想要返回所有這些類型的汽車,所有這些類型的汽車,但沒有其他的汽車,所有這些類型的汽車都沒有,或者是什麼? – 2012-01-27 13:45:00

+0

所有車型都具有AND類型,並且至少有一個來自OR組。您可以擁有任意數量的AND類型或OR組,並且在這些OR組中,您可以擁有任意數量的類型。 – 2012-01-27 13:49:10

回答

2

擴大我對科斯明的答案評論,這應該工作:

select car.id 
from car 
join type on car.id = type.id_car 
where type.type in 
('SUV','4x4','blue','red','US','Manual','Automatic','SemiAutomatic','diesel') 
group by car.id 
having count(distinct type.group)=6 
+0

它不起作用。因爲OR組中的類型可以增加計數,因此它不會用AND來覆蓋單個類型。 – 2012-01-27 14:27:57

+0

@CosminVacariou:你說每個''或''子句都是針對單個類型的值 - 例如。顏色都是第2組。這個子句在type.group的** distinct **值上 - 因此無論指定/選擇了多少顏色,計數只會增加1,無論有多少匹配顏色被選中。 – 2012-01-27 14:32:49

+0

是的,但你的IN不是基於組列。如果它是在組上它沒關係:) – 2012-01-27 14:49:31

0

這將做到這一點:

select car.* 
from car INNER JOIN (
        select id, count(*) countMatches 
        from car INNER JOIN type on car.id = type.id_car 
        where type in ('suv', '4x4', 'us', 'diesel','blue', 
            'red','manual', 'automatic') 
        group by id 
        having count(*) = 6 
        ) matches ON car.id = matches.id 
+0

它不是8,它是> 5 – 2012-01-27 13:45:39

+0

> 5仍然是不正確的。因爲你可以從5個ORed項目組中選擇5個。 – 2012-01-27 13:47:55

+0

@aF:Doh,謝謝,更新。 @ Cosmin:根據你提供的信息,這應該做你想做的。你的問題沒有提及任何有關組的內容,也沒有描述數據結構。如果你想要一個明確的答案,你應該提供問題中的所有相關信息。 – StevieG 2012-01-27 14:07:36

2

我認爲解決這個更好的辦法是要具體說明的類型,併爲這些創建列:

select * from car 
where type = 'SUV' 
and drive_type = '4x4' 
and (colour = 'blue' or colour = 'red') 
and origin = 'US' 
and (transmission = 'Manual' or transmission = 'Automatic') 
and fuel_type = 'diesel' 

然後你可以使用索引來提高查詢的性能。

0
select * from car c1 where c1.id in 
(
    select c.id from car c 
    inner join Type t on c.id = t.id_car and c.type in ('suv', '4x4', 'us', 'diesel', 'blue', 'red', 'manual', 'automatic') 
    group by c.id 
    having count(distinct *) > 5 
) 
+0

ps你不能使用與* – 2012-01-27 14:01:11

0

你有一個糟糕的設計。

每個組的價值都會進入一個新的列。

所以類型的表應該是:

id_car color transmission fuel origin_country etc 
1  blue automatic gas UK 
.... 

的查詢是:

select * 
from car join type on (car.id = type.id_car) 
where color in ('red', 'blue') 
and transmision in ('automatic') 
and country in ('US') 
etc. 
+0

是不同的,但事實並非如此。 – 2012-01-27 14:20:58

+0

我的例子不是很好的例子。在我的應用程序中真正的設計是可以的。 – 2012-01-27 14:34:00

+0

這是一個假想的情況?好的,在這種情況下,你可以保留ideea。這個設計是一個微弱的EAV,會導致你的問題:) – 2012-01-27 14:43:23