2010-06-11 86 views
0

我有兩個表。表A有一個id列。表B有一個Aid列和一個type列。示例數據:sql組合了兩個子查詢

A: id 
    -- 
    1 
    2 

B: Aid | type 
    ----+----- 
    1 | 1 
    1 | 1 
    1 | 3 
    1 | 1 
    1 | 4 
    1 | 5 
    1 | 4 
    2 | 2 
    2 | 4 
    2 | 3 

我想從表A中獲取所有ID,其中有一定數量的類型1和類型3操作。我的查詢是這樣的:

SELECT id 
FROM A 
WHERE (SELECT COUNT(type) 
     FROM B 
     WHERE B.Aid = A.id 
     AND B.type = 1) = 3 
    AND (SELECT COUNT(type) 
     FROM B 
     WHERE B.Aid = A.id 
     AND B.type = 3) = 1 

等上面的數據,僅僅是ID 1應返回。

我可以組合2個子查詢嗎?目標是使查詢運行得更快。

回答

1

postgres是否支持CTE?

WITH counts (Counts, Type, Aid) as (
    select count(type), type 
    from b group by Type, Aid 
) 
    select id 
    from A 
    join Counts B1 on b1.Aid = a.id and b1.type = 1 
    join Counts B3 on b3.Aid = a.id and b3.type = 3 
where 
    b1.counts = 3 and b3.counts = 1 

我建議比較執行計劃,但我懷疑這將是類似的,因爲一切都應該執行之前獲得倒塌。

+0

是,Postgres的支持WITH子句,因爲V8.4,包括遞歸:http://www.postgresql.org/docs/current/static/sql- select.html – 2010-06-11 21:27:46

0

這工作在TSQL,它在Postgres工作嗎?

SELECT A.ID 
FROM A 
WHERE A.ID in 
(
SELECT AID 
FROM B 
GROUP BY AID 
HAVING 
    SUM(CASE WHEN Type = 1 THEN 1 ELSE 0 END) = 3 
    OR SUM(CASE WHEN Type = 3 THEN 1 ELSE 0 END) = 1 
) 
0

另一種選擇:

SELECT DISTINCT Aid FROM (
    SELECT Aid,type,count(*) as n from B 
    GROUP BY Aid,type,) as g 
WHERE (g.n=1 AND g.type = 3) 
    OR (g.n=3 AND g.type = 1) 

我懷疑這將執行比原來的更好,雖然。 你似乎在做最好的策略:只計算候選行。 或許有些多餘的預過濾可以幫助:

SELECT DISTINCT Aid FROM (
    SELECT Aid,type,count(*) as n from B 
    WHERE g.type = 3 OR g.type = 1 -- prefilter 
    GROUP BY Aid,type,) as g 
WHERE (g.n=1 AND g.type = 3) 
    OR (g.n=3 AND g.type = 1) 
1
Select ... 
From A 
    Join (
      Select B.Id 
       , Sum (Case When B.Type = 1 Then 1 Else 0 End) As Type1Count 
       , Sum (Case When B.Type = 3 Then 1 Else 0 End) As Type3Count 
      From B 
      Where B.Type In(1,3) 
      Group By B.Id 
      ) As Z 
     On Z.Id = A.Id 
Where Z.Type1Count = 3 
    And Z.Type3Count = 1