Php 使用联接的复杂MySQL计数

Php 使用联接的复杂MySQL计数,php,mysql,Php,Mysql,基本上,现在的情况是有一个表,它通过用户名(UID)跟踪业务(BID)的签入$startday=一天的开始 Checkins: ID | UID | BID | DATE 然后还有第二张桌子,上面有朋友。用户可以是发送者或接收者 Friends: SENDER | RECIEVER | STATUS 我想做的是统计朋友的签到次数。So(伪码) 然后计算这些结果。我知道我需要做某种形式的连接,但我真的不知道从哪里开始这个设计。非常感谢您的帮助……试试这个 SELECT COUNT(1) F

基本上,现在的情况是有一个表,它通过用户名(UID)跟踪业务(BID)的签入$startday=一天的开始

Checkins:
 ID | UID | BID | DATE
然后还有第二张桌子,上面有朋友。用户可以是发送者或接收者

Friends:
 SENDER | RECIEVER | STATUS
我想做的是统计朋友的签到次数。So(伪码)

然后计算这些结果。我知道我需要做某种形式的连接,但我真的不知道从哪里开始这个设计。非常感谢您的帮助……

试试这个

SELECT COUNT(1) FROM Checkins ch
JOIN Friends fr
ON (fr.SENDER = ch.UID OR fr.RECIEVER = ch.UID)
WHERE ch.DATE = '$startday'

免责声明:这一点也不漂亮,而且可能会做得更整洁,我对它的性能没有任何要求,只是想给你一个起点,假设我正确理解了这个问题

假设:我假设:

  • 朋友的定义是处于发送者或接收者的任何关系中
  • 你需要一个人统计他们的朋友总共有多少人登记入住
  • 您可以添加自己的WHERE子句来指定要检查的日期范围
回答:下面的查询对我有效

SELECT COUNT(*) FROM checkins
INNER JOIN 
(
    SELECT DISTINCT friend FROM 
    (
        SELECT receiver AS friend FROM Friends
            WHERE sender = 1
        UNION ALL
        SELECT sender AS friend FROM Friends
            WHERE receiver = 1
    ) AS t 
) AS allfriends
    ON checkins.uid = allfriends.friend
示例数据:我使用的数据如下

签到

ID          UID         BID         Date
----------- ----------- ----------- ----------
1           1           1           NULL
2           2           1           NULL
3           3           1           NULL
4           4           1           NULL
5           5           1           NULL
6           6           1           NULL
7           1           1           NULL
8           2           1           NULL
9           3           1           NULL
10          4           1           NULL
朋友

sender      receiver    status
----------- ----------- -----------
1           2           NULL
1           3           NULL
1           4           NULL
2           3           NULL
2           5           NULL
2           6           NULL
3           1           NULL
2           1           NULL
解释:我将对其进行分解,以便您能够轻松理解(您可以单独运行其中的每一个以查看结果)

首先,我得到了一个用户朋友的所有ID列表,他们是发送者(uid1)

结果:

friend
-----------
2
3
4
friend
-----------
3
2
friend
-----------
2
3
4
3
2
friend
-----------
2
3
4
然后他们又是接受者

        SELECT sender AS friend FROM Friends
            WHERE receiver = 1
结果:

friend
-----------
2
3
4
friend
-----------
3
2
friend
-----------
2
3
4
3
2
friend
-----------
2
3
4
然后
将所有的
组合在一起,得到一个包含重复项的列表

        SELECT receiver AS friend FROM Friends
            WHERE sender = 1
        UNION ALL
        SELECT sender AS friend FROM Friends
            WHERE receiver = 1
结果:

friend
-----------
2
3
4
friend
-----------
3
2
friend
-----------
2
3
4
3
2
friend
-----------
2
3
4
通过
DISTINCT
子选择删除重复项

    SELECT DISTINCT friend FROM 
    (
        SELECT receiver AS friend FROM Friends
            WHERE sender = 1
        UNION ALL
        SELECT sender AS friend FROM Friends
            WHERE receiver = 1
    ) AS t 
结果:

friend
-----------
2
3
4
friend
-----------
3
2
friend
-----------
2
3
4
3
2
friend
-----------
2
3
4
最后,我使用
内部连接将checkins表加入到不同朋友的列表中
internaljoin
将从
checkins
中提取所有结果,其中
uid
也存在于我们的子选择
allfriends
中。添加COUNT(*)可获得所有行的计数

完整查询的结果:

6

然后,您可以使用
WHERE
,将日期选择围绕此进行包装,以便根据需要仅在两个日期之间获得结果

。我必须添加'AND ch.bid='$bid'和ch.uid'$uid',才能正确运行。