-2

次の行を持つinfo(名など...)を持つ「users」というテーブルがあります。

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回だけカウントされるため、結果は常に1になります。GROUPBYも無駄に試してみました。

では、重複を回避するためにdistinctを使用し、同時に1つだけでなく、常に同じ名前をカウントするにはどうすればよいですか?

このフィドルは、問題を自分でテストするために作成しました。

よろしくマイケル

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は、テーブルに2つの値があり、テーブルの別の2つの値questionsと一致して4になるためです。サブクエリで各値を計算してみてください。connections

于 2012-11-25T14:09:21.443 に答える
2

質問テーブルに ID があり、接続テーブルに ID が 1 つありますか? 持っている場合は、これを使用できます:

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'

ここでの唯一の問題は、counting 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 による 2 つの正解に加えて、インライン サブクエリを使用した 3 番目のオプションがあります。

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 に答える