-2

我有一个名为“用户”的表,其中包含以下行的信息(名字等...):

username
----------
mikha
guy
maricela

另一个名为“问题”的表包含以下行:

asker
----------
mikha
mikha
maricela
guy
maricela

另一个名为连接的表具有以下行:

username1
----------
guy
mikha
mikha

我想选择有关用户“mikha”的信息,包括当他是 questions.asker 和当他是 connections.username1 时的计数。我使用以下查询:

SELECT COUNT(questions.asker) AS asking,COUNT(connections.username1) AS following 
FROM users LEFT JOIN questions ON users.username = questions.asker 
LEFT JOIN connections ON users.username = connections.username1 
WHERE users.username = 'mikha'

预期成绩:

asking: 2 (as mikha is found 2 times asking)
following:  2 (as mikha is found 2 times following)

实际结果:

asking: 4
following: 4

如果我使用COUNT(DISTINCT questions.asker)并且COUNT(DISTINCT connections.username1)我得到的结果始终为 1,因为它只计算名称一次。我尝试了 GROUP BY 也无济于事。

那么,我怎样才能使用 distinct 来避免重复,同时在所有可用的时间都计算相同的名称,而不仅仅是一个?

我创建了这个小提琴来自己测试问题。

提前致谢 问候迈克尔

4

3 回答 3

3

试一试,

SELECT  a.*,
        b.totalAsk AS Asking,
        c.totalCount AS following
FROM    users a
        LEFT JOIN
        (
            SELECT  asker, COUNT(*) totalAsk
            FROM    questions
            GROUP BY asker
        ) b ON a.username = b.asker
        LEFT JOIN
        (
            SELECT  username1, COUNT(*) totalCount
            FROM    connections
            GROUP BY username1
        ) c ON a.username = c.username1
WHERE   a.username = 'mikha'

你得到的原因4是因为表上有两个值与表上的另外两个值questions相匹配,给它 4. 尝试计算子查询中的每个值。connections

于 2012-11-25T14:09:21.443 回答
2

您在问题表中有一个 ID,在连接表中有一个 ID?如果你有,你可以使用这个:

select
  users.username,
  count(distinct questions.id) as asking,
  count(distinct connections.id) as following
from
  users left join questions on users.username = questions.asker
  left join connections on users.username = connections.username1
where
  username='mikha'

编辑:根据您的评论,我认为您需要的是:

select
  COUNT(distinct questions.id) AS asking,
  COUNT(DISTINCT CONCAT(c1.username1,c1.username2)) AS following,
  COUNT(DISTINCT CONCAT(c2.username1,c2.username2)) AS followers
FROM
  users LEFT JOIN questions ON questions.asker=users.username
  LEFT JOIN connections c1 ON c1.username1=users.username
  LEFT JOIN connections c2 ON c2.username2=users.username
WHERE
  users.username = 'mikha'

这里唯一的问题是,count byCONCAT(...)没有利用索引并且可能很慢。CONCAT(userA, userB) = CONCAT(userC, userD)即使userA<>userC and userB<>userD. _ 您可以使用CONCAT(username1, ':', username2)来避免这种情况,但前提是您确保没有用户名包含:字符。但如果可能的话,我建议你在id你的连接表中添加一个。

于 2012-11-25T14:23:57.573 回答
1

除了@fthiella 和@Kuya John 的两个正确答案,这里是第三个选项,带有内联子查询:

SELECT  u.*,
        (   SELECT  COUNT(*) 
            FROM    questions AS q
            WHERE   u.username = q.asker 
        ) AS asking,
        (   SELECT  COUNT(*)
            FROM    connections AS c
            WHERE   u.username = c.username1
        ) AS following
FROM    users AS u
WHERE   u.username = 'mikha' ;
于 2012-11-25T14:43:35.047 回答