1

我什至不知道如何表达这个问题。我将给出示例内容和想要的输出,我正在寻找一个查询来做到这一点。

假设我有一个名为“标记”的表格,其中包含以下内容:

content_id | user_id
1          | 1
1          | 2
1          | 3
2          | 1
2          | 3
2          | 4
3          | 2
3          | 3
4          | 1
4          | 2
5          | 1
6          | 1
6          | 4

我在 content_ids 之间有一个不对称的关系:

master_content_id | slave_content_id
1                 | 2
3                 | 4
5                 | 6

对于每个“主”content_id(1、3 和 5),我想计算有多少不同的用户标记了主内容或从内容,但计算将两者标记为单个标记的人 - 这意味着在上面的示例中, content_id=1 由 user_id=1(作为 content_id=1 和 content_id=2)、按 user_id=2(作为 content_id=1)、按 user_id=3(作为 content_id=1 和 content_id=2)和按 user_id 计算=4(因为 content_id=2!)

我要进行的查询输出的一个示例是:

content_id | user_count
1          | 4          # users 1, 2, 3, 4
3          | 3          # users 1, 2, 3
5          | 2          # users 1, 4

我不能假设相关的 content_ids 总是连续的奇数/偶数(即 66 可以是从机 58 的主机)

我正在使用 MySQL,不介意使用它对 SQL 的扩展(而是查询是 ANSI,或者至少可移植到大多数数据库)

4

4 回答 4

3

下面的查询对我有用。

我正在使用带有 a 的子查询UNION ALL来处理您的映射内容等于直接内容。

SELECT master_content_id AS content_id,
       COUNT(DISTINCT user_id) AS user_count
FROM (
  SELECT master_content_id, slave_content_id
    FROM relationship
  UNION ALL
  SELECT master_content_id, master_content_id
    FROM relationship
) r
JOIN flagged f ON ( f.content_id = r.slave_content_id )
GROUP BY master_content_id

结果:

content_id  user_count
         1           4
         3           3
         5           2
于 2012-05-03T10:18:51.503 回答
2

我认为这样的事情对你有用(虽然GROUP_CONCAT是 MySQL 特定的,但可以在其他 RDBMS 中实现类似的连接)

SELECT  COALESCE(Master_Content_ID, Content_ID) AS Content_ID,
        COUNT(DISTINCT User_ID) AS Users,
        CONCAT('#Users ', GROUP_CONCAT(DISTINCT User_ID ORDER BY User_ID)) AS UserList
FROM    Flagged
        LEFT JOIN MasterContent
            ON Content_ID = Slave_Content_ID
GROUP BY COALESCE(Master_Content_ID, Content_ID)

此处的 SQL Fiddle 示例:http ://www.sqlfiddle.com/#!2/d09be/2

输出:

CONTENT_ID  USERS   USERLIST
1           4       #Users 1,2,3,4
3           3       #Users 1,2,3
5           2       #Users 1,4
于 2012-05-03T10:25:22.230 回答
1

从给出的示例中,这是否可以完成工作(我没有可用于测试的 MySQL)?

SELECT 
    ms.master_content_id,
    (SELECT COUNT(DISTINCT f.user_id) FROM flagged f WHERE
                      f.content_id = ms.slave_content_id OR
                      f.content_id = ms.master_content_id)
FROM
    master_slave ms

最好不要有 DISTINCT,但我看不到绕过它的方法。

于 2012-05-03T10:24:59.410 回答
1
SELECT master_content_id      AS content_id
     , COUNT(*)               AS user_count
     , GROUP_CONCAT(user_id)  AS flagging_users
FROM 
  ( SELECT r.master_content_id 
         , f.user_id
    FROM relationship AS r
      JOIN flagged AS f
        ON f.content_id = r.master_content_id
  UNION 
    SELECT r.master_content_id
         , f.user_id
    FROM relationship AS r
      JOIN flagged AS f
        ON f.content_id = r.slave_content_id
  ) AS un
GROUP BY master_content_id
于 2012-05-03T10:34:28.640 回答