困难的MySQL查询

时间:2011-07-09 22:39:09

标签: mysql sql query-optimization

在我们的数据库表中,我们保留了许多计数列,以帮助减少复杂查找查询的数量。例如,在我们的用户表中,我们列出了所写的评论数量,上传的照片,朋友,关注者等。为了确保这些评论保持同步,我们有一个定期运行的脚本来检查和更新这些计数列。< / p>

我一直在尝试编写一个有效的查询来计算特定用户拥有的朋友数量,但却无法弄清楚如何去做。在我们的朋友模特中,如果他们将您添加为朋友(无需确认),则他是朋友,因此在添加您添加的朋友数量加上添加了您的人数时,您必须计算独特人数作为朋友。

以下是两个查询,每个查询都用于更新用户表中所有行的朋友计数,以便在单个方向上建立友谊。我无法弄清楚如何将它们组合在一起,以便获得用户拥有的唯一朋友的总数:

将您添加为好友的用户

UPDATE users 
  JOIN (SELECT cid2, COUNT(*) as c 
         FROM connections 
         JOIN users ON connections.cid1 = users.user_id
        WHERE connection_type = "MM" 
          AND connections.status="A" 
          AND users.status != "D"
     GROUP BY cid2) f ON f.cid2 = users.user_id 
   SET users.friends = f.c
 WHERE users.status != "D";

您添加为好友的用户

UPDATE users u 
  JOIN (SELECT cid1, COUNT(*) as c
          FROM connections 
          JOIN users ON connections.cid1 = users.user_id 
         WHERE connection_type = "MM" 
           AND connections.status = "A" 
           AND users.status != "D" 
      GROUP BY cid1) f ON f.cid1 = users.user_id 
   SET users.friends = f.c
 WHERE users.status != "D";

3 个答案:

答案 0 :(得分:1)

尝试3 ...

UPDATE
  users 
INNER JOIN
(
  SELECT
    connections.cid1  AS user_id,
    COUNT(*)          AS total
  FROM
  (
    SELECT cid1, cid2 FROM connections WHERE connection_type = 'MM' AND status = 'A'
    UNION
    SELECT cid2, cid1 FROM connections WHERE connection_type = 'MM' AND status = 'A'
  )
    AS connections
  INNER JOIN
    users
      ON  users.user_id = connections.cid2
      AND users.status != 'D'
  GROUP BY
    connections.cid1
)
  AS friends
    ON friends.user_id = users.user_id 
SET
  users.friends = friends.total
WHERE
  users.status != 'D';

(OP请求时删除了其他选项。如果感兴趣,请参阅编辑历史记录。)

答案 1 :(得分:0)

您可以将其编写为存储过程,同时执行SELECT COUNT()并将其添加到计数器变量,然后发出单个UPDATE

答案 2 :(得分:0)

状态标志有多重要?尝试使用引用同一个表的子查询更新users表时,您将遇到麻烦。

考虑:

UPDATE connections SET status='D' WHERE cid1 IN 
(SELECT user.id
 FROM users u
 WHERE status='D');

UPDATE connections SET status='D' WHERE cid2 IN 
(SELECT user.id
 FROM users u
 WHERE status='D');

UPDATE users u
SET friends = (
  SELECT COUNT(DISTINCT friend)
  FROM (
   SELECT c1.cid2 as friend
   FROM connections c1
    WHERE c1.connection_type = 'MM' 
      AND c1.connections.status='A'
      AND c1.status<>'D'
      AND c1.cid1=u.id 
   UNION
   SELECT c2.cid1 AS friend
   FROM connections c2
    WHERE c2.connection_type = 'MM' 
      AND c2.connections.status='A'
      AND c2.status<>'D'
      AND c2.cid1=u.id 
   )
)