2010-07-28 114 views
1

我有這樣的查詢選擇用戶註冊等在過去30天數:選擇用戶在過去30天,過去7天簽署了一個高效的查詢

SELECT 
    COUNT(*) AS UserCount30 
FROM 
    User 
WHERE 
    User.UserDateCreated > (CURDATE() - INTERVAL 30 DAY) 

然後,我有這個查詢選擇過去7天內註冊的用戶數

SELECT 
    COUNT(*) AS UserCount7 
FROM 
    User 
WHERE 
    User.UserDateCreated > (CURDATE() - INTERVAL 7 DAY) 

理想情況下,這些都將成爲一個較大查詢的一部分。我怎麼能在一個有效的查詢中得到這兩個值,最好不使用子查詢。

+0

我認爲您正在考慮過去7天內註冊的用戶成爲過去30天內註冊用戶的子集? (你希望它們包含在兩個計數中?) – dave 2010-07-28 20:56:11

+1

@dave當然。在過去7天內註冊的用戶也是在過去30天內註冊的用戶。 – Backus 2010-07-28 21:15:35

回答

0

爲什麼不使用子查詢?由於'所有子查詢都很慢'的神話?

這裏

SELECT 
u1.cnt AS UserCount30, 
u2.cnt AS UserCount7 
FROM (SELECT 
    COUNT(*) AS cnt 
FROM 
    User 
WHERE 
    User.UserDateCreated > (CURDATE() - INTERVAL 30 DAY) 
) AS c1 
CROSS JOIN (SELECT 
    COUNT(*) AS cnt 
FROM 
    User 
WHERE 
    User.UserDateCreated > (CURDATE() - INTERVAL 7 DAY) 
) AS c2
6

做拉30天,對COUNT(*)。然後做一筆款項,因爲expr總額有一個if語句,如果它在7天內返回1,否則返回1。

SELECT COUNT(*) AS UserCount30, 
     SUM(if((CURDATE() - INTERVAL 7 DAY) < User.UserDateCreated) 1 else 0) 
    FROM USER 
WHERE User.UserDateCreated > (CURDATE() - INTERVAL 30 DAY) 
+0

@OMG小馬感謝您的格式! – coffeepac 2010-07-28 21:28:54

0
SELECT 
    SUM(if((CURDATE() - INTERVAL 30 DAY)< User.UserDateCreated) 1 else 0) AS Last30, 
    SUM(if((CURDATE() - INTERVAL 7 DAY)< User.UserDateCreated) 1 else 0) AS Last7 
FROM 
    USER 

我喜歡coffeepac的答案,但改變只是一個小(更易於閱讀/理解它在做什麼這樣,恕我直言)

我不是一個mySQL的傢伙,但有一點我會小心的是,如果UserDateCreated是像Sql-Server使用的「日期/時間」字段。在這種情況下,最好先抽出時間,然後再進行邏輯比較(<,>,=,...)比較。

+0

在這一個中,Last7s不會被計算兩次嗎?也就是說,他們在過去30年內和過去7年內註冊過。 – Chris 2010-07-28 21:04:21

+0

是的 - 我通過@bball驗證過 - 在過去7天內註冊過的任何用戶都應該處於這兩種狀態。 – dave 2010-07-28 21:53:50