1

我将仅解释与问题相关的内容,并省略任何其他不相关的细节。

现在的情况:

我有两张桌子,硬币和用户。

coin有三个字段id, uid, fid. 用户(已经在系统中注册并且可以邀请朋友)和他们的朋友(已经接受邀请并且成为会员)之间的硬币表。-该表仅存储被邀请后的成功注册-

id是唯一索引。
uid是存储用户ID。
fid是存储好友id(接受邀请并成为系统成员的好友)。

users具有有关用户的常用信息,例如id, fname, lname, email...etc 和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 个用户)-> 777,123 和 789,用户 444 邀请了 2 个用户,用户 555 只邀请了 1 个用户,但对于 555,由于他的朋友(999)在 2012 年之后注册,因此不会被计算在内-08-31

我想要的是用户

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

到目前为止我所做的是:[完全不确定]

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之前接受邀请并注册。在该日期之后任何其他接受的邀请都不应计算在内。

请为我提供代码示例。

4

5 回答 5

2

您可以SUM结合使用CASE

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
于 2012-10-11T12:18:24.367 回答
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

编辑修复了数据格式

于 2012-10-11T12:30:50.493 回答
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
于 2012-10-11T12:34:54.960 回答
0

count(expression)函数计算该表达式的结果不为空的行。如果表达式只返回 true 或 false,所有行都将被计算在内,因为 true 和 false 都不为空。

要使用带有 count 的表达式,您必须使其在 false 时返回 null:

 COUNT(friend.date_create < '2012-10-31' or null) AS NoOfFriends
于 2012-10-11T12:37:50.333 回答
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 ...)不清楚。

于 2012-10-12T10:27:39.250 回答