2011-07-01 48 views
1

我需要找到用戶數:如何讓sql更高效。只需要計數

  1. 誰擁有一個或多個風扇
  2. 誰擁有兩個風扇
  3. 誰擁有三個風扇

這裏是SQL我開發得到的答案#1

SELECT users.id, count(fans.id) 
    FROM users 
    JOIN fans on users.id = fans.user_id 
GROUP BY users.id 
    HAVING COUNT(fans.id) > 0 

上面的查詢工作,但我得到所有用戶記錄,然後我計算數組的大小。當用戶數量達到數千時,它的性能非常糟糕。我如何重構查詢,以便我只能得到用戶的數量?

我正在使用mysql,但我可能需要使用postgresql的另一個項目。

+0

並非所有需要的信息都在表格「粉絲」中?我沒有看到加入「用戶」表的理由。如果您只有數千行的性能問題,請確保您的統計數據是最新的,並查看查詢的執行計劃。 –

回答

2

子查詢將很好地做。

Select 
    Count(user.id) 
from 
    Users 
Where 
    (Select Count(fans.id) from Fans where user_id = users.id) > 0 
+0

這就像魅力。謝謝。今天也學到了新東西。 –

+0

我認爲@尼古拉斯凱里的答案有更少的開銷,並給出了你所問的所有三個選項。既然你發現上面的確定,你可以嘗試SELECT COUNT(DISTINCT user.id)FROM Fans – niktrs

2

嘗試這種情況:

select usersWithOneOrMoreFans = sum(case when t.fan_count >= 1 then 1 else 0 end) , 
     usersWithTwoFans  = sum(case when t.fan_count = 2 then 1 else 0 end) , 
     usersWithThreeFans  = sum(case when t.fan_count = 3 then 1 else 0 end) 
from (select user_id as user_id , 
       count(*) as fan_count , 
     from fans 
     group by fans.user_id 
    ) t 

[編輯以除去無意義表參考]

+0

哇。我不知道在sql中可以像真正的編程語言代碼那樣編寫代碼。我希望我能夠與你分手。 –

+1

SQL **是一種真正的編程語言,圖靈完整和全部。這不僅僅是一種**程序性語言。這都是關於設置操作。並不是說這就是說SQL適合於一般用途的工作:它是爲特定的問題空間而設計的。 –

0
select num_users_with_fans, num_users_with_two_fans,num_users_with_three_fans 
from(
    select count(1) as num_users_with_fans 
    from(
     select users.id, count(fans.id) 
     from users join fans on users.id = fans.user_id 
     group by users.id 
     having count(fans.id) > 0 
    )a 
cross join(
    select users.id, count(fans.id) as num_users_with_two_fans 
    from users join fans on users.id = fans.user_id 
    group by users.id 
    having count(fans.id)=2 
)b 
cross join(
    select users.id, count(fans.id) as num_users_with_three_fans 
    from users join fans on users.id = fans.user_id 
    group by users.id 
    having count(fans.id)=3 
)c 
0

這裏是我的:

SELECT nfans, count(*) AS nusers FROM 
    (SELECT count(fans.id) AS nfans FROM fans GROUP BY user_id) foo 
GROUP BY nfans 

這會給你的用戶 「nusers」 其中有 「nfans」 粉絲數量。

如果你想剪切到最大的3個風扇:

SELECT nfans, count(*) AS nusers FROM 
    (SELECT least(3,count(fans.id)) AS nfans FROM fans GROUP BY user_id) foo 
GROUP BY nfans 

在這種情況下,BIN「nfans = 3」包含有3隊或更多的球迷用戶的數量。