2012-10-11 36 views
1

我會單獨解釋與問題相關的內容,並省略其他不相關的細節。我可以放一個條件來過濾我的COUNT子句嗎? mysql

現狀:

我有兩個表,硬幣和用戶。

coin有三個字段id, uid, fid.用戶之間 硬幣表涉及(誰已經在系統中登記,並能邀請朋友)和他們的朋友(誰已經接受了邀請,也成爲會員。):表示該表只有在被邀請成功註冊後才能成功註冊 -

id是唯一索引。
uid是存儲用戶ID。
fid用於存儲朋友id(接受邀請併成爲系統成員的朋友)。

users有關於用戶如id, fname, lname, email ...等,並date_create

通常信息目的: 要找到贏家誰取得了大多數的邀請。換一種說法。 要找到邀請人數最多的頂級用戶及其受邀朋友,必須在2012-08-31之前註冊。日期存儲在表'用戶'列date_create中。日期格式爲YYYY-MM-DD

例 -

Table coin 

    id uid fid 
    1 333 777 
    2 444 888  
    3 555 999  
    4 333 123   
    5 444 456   
    6 333 789 

Table users 
    id date_create 
    333 2012-07-15 
    444 2012-07-20 
    555 2012-07-25 
    777 2012-07-25 
    888 2012-07-25 
    999 2012-10-02 <-- I don't need this to be counted 
    123 2012-07-25 
    456 2012-07-25 
    789 2012-07-25 

意味着用戶333具有最多數目的邀請(邀請3個用戶) - > 777123和789 和用戶444邀請2組的用戶和用戶555只邀請1個用戶,但555不會因爲他的後2012-08-31

註冊的朋友(999)進行計數我要的是用戶

333 has made 3 invitations before 2012-08-31. 
444 has made 2 invitations before 2012-08-31. 

我做了這麼多遠:[TOTALLY不知道這]

SELECT 
    c.uid,  
    u.fname, 
    u.lname, 
    u.phone, 
    u.email, 
    u.country, 
    COUNT(c.fid) AS NoOfFriends 
FROM coin AS c 
    JOIN users AS u 
    ON c.uid = u.id 
GROUP BY c.uid 
ORDER BY NoOfFriends desc 

該查詢帶來了(據我所知)與最邀請用戶無論何時他/她的朋友已經註冊的。

所以我的問題是: Q1)如何將日期條件應用到我的查詢中?

我想擁有最多的朋友邀請的用戶。他/她邀請的朋友必須在2012-08-31之前接受邀請並註冊。在該日期之後的任何其他接受的邀請不應計入在內。

請爲我提供代碼示例。

+1

你的問題不是很清楚。如果你只問一個問題,而不是同時提出兩個問題,那將更加清晰。如果你有兩個問題,那麼選擇一個,然後首先問一個問題。如果你仍然需要更多的幫助,你以後可以隨時創建另一個問題。讓每個問題都清晰,準確和獨立,避免一次混合多件事,否則你只會迷惑自己和其他人。 –

+0

刪除了第一個問題。謝謝你的評論。 – MJoraid

+0

「用戶必須在2012年10月31日之前註冊」哪個表格包含註冊日期以及該列的名稱是什麼?表'用戶'列date_create中的 –

回答

2

很多問題的答案混淆與被邀請的朋友的實際用戶。

SELECT 
    c.uid 
info.fname, 
info.lname, 
info.phone, 
info.email, 
info.country, 
info.date_create, 
    COUNT(c.fid) AS [NoOfFriends] 
FROM coin AS c 
    JOIN users AS friend 
     ON c.fid = friend.id 
    LEFT JOIN users AS info 
     ON c.uid = info.id 
WHERE friend.date_create < '20121031' 
GROUP BY c.uid 

編輯固定數據格式

+0

準確。 +1「很多答案讓實際用戶和被邀請的朋友感到困惑。」每次我嘗試獲取日期時,我都會得到用戶創建日期而不是受邀朋友的日期。 – MJoraid

+0

使用文化特定的日期格式不值得投票支持,但它幾乎是......除非您在查詢中專門設置了語言/日期格式,否則您應該使用文化非特定格式'yyyyMMdd',因爲沒有辦法可以轉換爲錯誤/無效的日期。 – GarethD

+1

@GarethD - 在技術上正確是最好的一種。我會吞下我們的驕傲,並使用文化不可知的日期格式。 –

2

您可以結合使用SUMCASE

SUM(CASE WHEN <cond> THEN 1 ELSE 0 END) as NoOfFriends 

完整的語句應該是這個樣子:

SELECT 
    c.uid, 
    u.fname, 
    u.lname, 
    u.phone, 
    u.email, 
    u.country, 
    u.`date_create`, 
    SUM(CASE WHEN f.date_create < 2012-10-31 THEN 1 ELSE 0 END) AS NoOfFriends 
FROM coin AS c 
    JOIN users AS u 
    ON c.uid = u.id 
    join users as f 
    on c.fid = f.id 
GROUP BY c.uid, u.fname, u.lname, u.phone, u.email, u.country, u.`date_create` 
ORDER BY NoOfFriends desc 
+0

在這裏值得一提的是,你可以通過在group子句後面使用HAVING子句來過濾「NoOfFriends」。 (只爲那些不知道這個) SUM/CASE組合是我真正喜歡和使用的東西。 –

+0

您也可以將它簡化爲SUM(),因爲布爾條件評估爲1或0,但我認爲這可能是SQL的MySQL擴展。 – Barmar

+0

@Barmar:的確,這是一個MySql擴展。例如,它在Oracle中不起作用。 –

0

你的只有c.uid分組將在MySQL的工作方法,但你會成爲脫膠與其他RDBMS。

在這種情況下,我會將計數移動到子查詢中,在我看來,它更易於閱讀,並且它很好地分離出您希望應用的邏輯的查詢,即獲取朋友註冊的所有邀請某個日期,然後加入到邀請他們的用戶。

SELECT u.ID, 
     u.fname, 
     u.lname, 
     u.phone, 
     u.email, 
     u.country, 
     u.`date_create`, 
     COALESCE(FriendCount, 0) AS FriendCount 
     COALESCE(FriendCount2, 0) AS FriendCount2 
FROM users AS u 
     LEFT JOIN 
     ( SELECT coin.UID, 
        COUNT(coind.fid) AS FriendCount, 
        COUNT(CASE WHEN Users.Date_Create < '20121031' THEN coind.fid END) AS FriendCount2 
      FROM coin 
        INNER JOIN Users 
         ON coin.FID = users.ID 
      GROUP BY coin.UID 
     ) c 
      ON c.uid = u.id 
ORDER BY FriendCount2 DESC 

如果你不關心總的朋友,只有那些10月31日之前,那麼可以簡化這

SELECT u.ID, 
     u.fname, 
     u.lname, 
     u.phone, 
     u.email, 
     u.country, 
     u.`date_create`, 
     COALESCE(FriendCount, 0) AS FriendCount 
FROM users AS u 
     LEFT JOIN 
     ( SELECT coin.UID, 
        COUNT(coind.fid) AS FriendCount 
      FROM coin 
        INNER JOIN Users 
         ON coin.FID = users.ID 
      WHERE Users.Date_Create < '20121031' 
      GROUP BY coin.UID 
     ) c 
      ON c.uid = u.id 
ORDER BY FriendCount DESC 
0

count(expression)函數計算的行,其中表達式的結果是不爲空。如果表達式返回true或false,則所有行將被計數,因爲true和false都不爲null。

要使用表達式與計必須使否則爲false返回null:

COUNT(friend.date_create < '2012-10-31' or null) AS NoOfFriends 
+0

但date_create是在另一個字段?計數如何訪問兩個表並檢查。它需要從基於uid的硬幣中獲得fid,然後在用戶中查看date_create以獲得fid,如果日期在20120831之前,那麼它應該被計數,否則,轉到與uid相關的下一個fid。 – MJoraid

0

這就是我的答案,謝謝大家誰嘗試,並幫助,特別是LastCoder誰迅速提供實際的解決方案。

SELECT 
    c.uid, 
    info.id, 
    info.fname, 
    info.lname, 
    info.phone, 
    info.email, 
    info.country, 
    COUNT(DISTINCT c.fid) AS NoOfFriends -- modified this to get unique invitations 
FROM coin c 
    JOIN users AS friends 
    ON c.fid = friends.id 
    LEFT JOIN users AS info 
    ON c.uid = info.id 
WHERE friends.date_create < '20120831' 
GROUP BY c.uid 
ORDER BY NoOfFriends DESC 
LIMIT 10 

說實話,我沒有使用其他的解決方案,因爲我不明白SUM(CASE WHEN ...)清楚。

相關問題