MYSQL:带有详细信息和未读邮件数的朋友列表

时间:2019-06-20 06:09:06

标签: mysql

我正在使用聊天系统,希望列出未读邮件数的朋友详细信息。

表结构如下

用户

id
name

朋友

id
sender_id
recipient_id

消息

id
from_id
to_id
read_at

使用以下查询详细获取用户的朋友数据

(SELECT U.id, U.name 
   FROM users U LEFT JOIN friends F 
     ON U.id = F.recipient_id 
  WHERE F.sender_id = 2) 
UNION 
(SELECT U.id, U.name 
   FROM users U LEFT JOIN friends F 
     ON U.id = F.sender_id 
  WHERE F.recipient_id = 2) 
ORDER BY name ASC

查询给我完美的结果,返回用户2的朋友,但我希望未读消息计数(WHERE read_at = NULL)与朋友列表一起显示。如何通过查询实现?

结果列就像

+----+-------+---------------+
| id | name  | message_count |
+----+-------+---------------+
|  1 | One   |             1 |
|  3 | Two   |             4 |
|  4 | Three |            10 |
+----+-------+---------------+

我尝试了以下查询,但没有成功

(SELECT U.id, U.name, COUNT(M.id) as message_count 
   FROM users U LEFT JOIN friends F 
     ON U.id = F.recipient_id LEFT OUTER JOIN messages M 
     ON  M.from_id = U.id 
    AND M.read_at IS NULL 
  WHERE F.sender_id = 2) 
UNION 
(SELECT U.id, U.name, COUNT(M.id) as message_count 
   FROM users U LEFT JOIN friends F 
     ON U.id = F.sender_id LEFT OUTER JOIN messages M 
     ON M.from_id = U.id 
    AND M.read_at IS NULL 
  WHERE F.recipient_id = 2) 
ORDER BY name ASC

有人可以帮助我吗?致谢,谢谢大家

2 个答案:

答案 0 :(得分:0)

您过于复杂了。尽管没有表的示意图很难分辨,但类似的事情还是可以的:

SELECT U.id, U.name, COUNT(M.id) FROM users U 
INNER JOIN friends F 
ON (U.id = F.recipient_id AND F.sender_id = 2) 
   OR (F.recipient_id = 2 AND U.id = F.sender_id)
LEFT JOIN messages M
ON M.to_id = 2 AND M.from_id = U.id
WHERE M.read_at IS NULL
GROUP BY M.from_id
ORDER BY name ASC

答案 1 :(得分:0)

如果friends.recipient_id是您的登录用户,则应该可以使用这种方法

public function getMarketcapData($page = -1, $limit = -1){
      $pageAndCount = $page>-1 && $limit>0;
      $qb = $this->getEntityManager()->createQueryBuilder();

      $q  = $qb->select('cc, count(cr) as coinRawsCount, cmc as relatedCategory')
              ->from('AppBundle:CoinClean', 'cc')
              ->leftJoin("AppBundle:CoinRaw", "cr",  'WITH', 'cc = cr.coinClean')
              ->leftJoin("AppBundle:CoinMapCategory", "cmc", 'WITH', 'cc.relatedCategory = cmc')
              ->andWhere('cc = cr.coinClean')
              ->andWhere('cc.relatedCategory = cmc')
              ->groupBy('cc.id')
      ;

      if($pageAndCount) $q = $q->setFirstResult($page*$limit)->setMaxResults($limit);

      $q= $q->orderBy('cc.rank', "ASC")->getQuery();

      $result = $q->getResult();
      if($pageAndCount){
          $qb = $this->getEntityManager()->createQueryBuilder();
          $q = $qb->select('count(u.id)')->from('AppBundle:CoinClean', 'u')->getQuery();
          return new PageResult($result, (int)$q->getSingleScalarResult(), $page, $limit );
      }else{
          return $result;
      }
  }