加入多个表并使用Count with MySQL

时间:2016-03-09 14:06:24

标签: mysql join left-join inner-join

所以我让自己陷入了混乱的困境中。

基本上,我有一个小社交网络应用程序,我需要将4个不同的表组合成一个视图。

  • 表1 - 用户帖子
  • 表2 - 用户
  • 表3 - 喜欢
  • 表4 - 评论

然后我需要返回一个帖子列表,其中包含用户详细信息,然后分别为每个帖子添加喜欢数量和评论数量的列。

如果帖子没有任何喜欢或评论,那么理想情况下我们应该显示零。

下面的查询加入了所有内容,但返回了所有内容的多行,因为它为每个注释返回1行或类似。

任何能够帮助我将这些结合在一起的人吗?

SELECT *
FROM app_posts AS p
LEFT JOIN app_comments AS c ON c.post_id = p.post_id
LEFT JOIN app_user AS u ON u.user_id = p.user_id
LEFT JOIN app_likes AS l ON l.post_id = p.post_id
WHERE u.user_banned = 0
AND p.post_public = 1
ORDER BY p.post_date DESC

非常感谢任何帮助!

表格列如下;

app_likes

  • like_id
  • POST_ID
  • USER_ID
  • liked_date

app_comments

  • COMMENT_ID
  • comment_user_id
  • POST_ID
  • comment_body
  • COMMENT_DATE

app_posts

  • POST_ID
  • USER_ID
  • POST_CONTENT
  • POST_DATE
  • post_public

APP_USER

  • USER_ID
  • user_first
  • user_last
  • user_avatar
  • user_banned

目前返回的内容示例如下(为了方便而简化)

enter image description here

您将看到post_id重复多次。

我想要它返回的是post_id只有一次,并且有'喜欢'和评论'在新栏目中(我不知道如何做到这一点)。

西蒙

3 个答案:

答案 0 :(得分:0)

您可能缺少GROUP BY ...

SELECT p.*,u.*,count(distinct c.comment_id),count(distinct l.like_id)
FROM app_posts AS p
LEFT JOIN app_comments AS c ON c.post_id = p.post_id
LEFT JOIN app_user AS u ON u.user_id = p.user_id
LEFT JOIN app_likes AS l ON l.post_id = p.post_id
WHERE u.user_banned = 0
AND p.post_public = 1
GROUP BY p.post_id
ORDER BY p.post_date DESC

请注意,MySQL可以像你这样使用GROUP BY,但很多其他数据库would require你要打破" p.*"明确MAX(p.post_id),MAX(p.post_content),等。

答案 1 :(得分:0)

fs.readdirSync

答案 2 :(得分:0)

尝试在查询结尾处添加分组依据,例如

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "philo.h"
#include "extern.h"

void                    philosoph_comportement(t_philosop *philosop)
{
  int                   i = 0;
  if ((pthread_mutex_lock(philosop->chopsticks1)) == 0)
    {
      printf("%s\n", "Taking left stick");
      lphilo_take_chopstick(philosop->chopsticks1);
      i++;
    }
  if ((pthread_mutex_lock(philosop->chopsticks2)) == 0)
    {
      printf("%s\n", "Taking right stick");
      lphilo_take_chopstick(philosop->chopsticks2);
      i++;
    }
  if (i == 2)
    {
      printf("%s\n", "Eat");
      lphilo_eat();
      sleep(1);
      printf("%s\n", "Sleep");
      pthread_mutex_unlock(philosop->chopsticks1);
      pthread_mutex_unlock(philosop->chopsticks2);
      lphilo_release_chopstick(philosop->chopsticks1);
      lphilo_release_chopstick(philosop->chopsticks2);
      lphilo_sleep();
    }
}

void                    *start_routine(void *arg)
{
  t_philosop            *philosop;
  int                   i;

  i = 0;
  philosop = (t_philosop *)arg;
  while (i != philosop->nbr_occ)
    {
      philosoph_comportement(philosop);
      i++;
    }
  return (0);
}

int                     create_threads_mutex(int nbr_philo, int occurences)
{
  int                   i;
  t_philosop            *philosop;
  pthread_mutex_t       *chopsticks;

  i = -1;
  if ((chopsticks = malloc(sizeof(pthread_mutex_t) * nbr_philo)) == NULL)
    return (2);
  if ((philosop = malloc(sizeof(t_philosop) * nbr_philo)) == NULL)
    return (2);
  while (++i != nbr_philo)
    {
      philosop[i].nbr_occ = occurences;
      philosop[i].chopsticks1 = &chopsticks[i];
      if (i - 1 < 0)
        philosop[i].chopsticks2 = &chopsticks[nbr_philo];
      else
        philosop[i].chopsticks2 = &chopsticks[i - 1];
    }
  i = -1;
  while (++i != nbr_philo)
    pthread_create(&philosop[i].philosophers, NULL, start_routine, &philosop[i]);
  i = -1;
  while (++i != nbr_philo)
    {
      printf("Philo number : %d\n", i);
      pthread_join(philosop[i].philosophers, NULL);
    }
  return (0);
}

int                     parse_arg(char **argv, int *philo, int *occ)
{
  if (strcmp(argv[1], "-p") == 0 && strcmp(argv[3], "-e") == 0 &&
      argv[2] != NULL && argv[4] != NULL)
    {
      *philo = atoi(argv[2]);
      *occ = atoi(argv[4]);
    }
  else if (strcmp(argv[1], "-e") == 0 && strcmp(argv[3], "-p") == 0 &&
           argv[2] != NULL && argv[4] != NULL)
    {
      *philo = atoi(argv[4]);
      *occ = atoi(argv[2]);
    }
  else
    return (2);
  return (0);
}

int                     main(int argc, char **argv)
{
  int                   philo;
  int                   occurences;

  philo = 0;
  occurences = 0;
  if (argc != 5)
    return (2);
  if ((parse_arg(argv, &philo, &occurences)) == 2)
    return (2);
  RCFStartup(argc, argv);
  if ((create_threads_mutex(philo, occurences)) == 2)
    return (2);
  RCFCleanup();
  return (0);
}