2017-10-10 75 views
2

我具備這些表的數據庫:如何有SQL查詢2級的子查詢分爲

  1. 用戶(ID,電子郵件)
  2. 旅行(ID,driver_id)
  3. MatchedTrips(ID,trip_id )

我需要爲每個用戶獲得他創建的旅行總數除以找到的總匹配數。

我一直在爲此構建原始SQL查詢。這是我試過的,並且確定它遠沒有正確。

SELECT 
    users.email, 
    total_trips.count1/total_matches.count2 
FROM users CROSS JOIN (SELECT 
     users.email, 
     count(trips.driver_id) AS count1 
     FROM trips 
     INNER JOIN users ON trips.driver_id = users.id 
     GROUP BY users.email) total_trips 
     CROSS JOIN (SELECT users.email, count(matches.trip_id) AS count2 
        FROM matches 
        LEFT JOIN trips ON matches.trip_id = trips.id 
        LEFT JOIN users ON trips.driver_id = users.id 
        GROUP BY users.email) total_matches; 

回答

1

最簡單的方法可能是使用count(distinct)

select u.email, 
     count(distinct t.id) as num_trips, 
     count(distinct m.id) as num_matches, 
     (count(distinct t.id)/count(distinct m.id)) as ratio 
from users u left join 
    trips t 
    on t.driver_id = u.id left join 
    matches m 
    on m.trip_id = t.trip_id 
group by u.email; 

注意:如果郵件是唯一的,那麼查詢可以簡化。在某些情況下,count(distinct)可能很昂貴。

+0

我認爲這個查詢需要處理除零的情況,並且是的電子郵件是唯一的。感謝Gordon的幫助。 –

+1

@IslamWazery。 。 。您的原始查詢不處理這種情況。但很容易:'(count(distinct t.id)/ nullif(count(distinct m.id),0))'。 –

+0

謝謝你,我接受你的答案,因爲它真的是我需要的。 –

2

你可以算出這樣的方式爲每個驅動程序的總人次及總比賽:

select driver_id, count(t.id) as total_trips, count(m.id) as total_matches 
from trips t 
left join matches m on (t.id = trip_id) 
group by 1 

使用該查詢作爲派生表與users加入:

select email, total_trips, total_matches, total_trips::dec/ nullif(total_matches, 0) result 
from users u 
left join (
    select driver_id, count(t.id) as total_trips, count(m.id) as total_matches 
    from trips t 
    left join matches m on (t.id = trip_id) 
    group by 1 
    ) s on u.id = driver_id 
order by 1; 

SQLFiddle.