mysql - 具有多个左连接的查询 - points 列值不正确

标签 mysql database join left-join

我有以下数据库结构,我正在尝试运行一个查询,该查询将显示教室和教室中有多少学生,教室分配了多少奖励,以及分配了多少分到单个教室(基于 classroom_id 列)。

我试图使用最底部的查询来收集教室分配的“totalPoints”——基于计算 classroom_redeemed_codes 表中的点列并将其作为单个整数返回。

由于某些原因,totalPoints 的值不正确 - 我做错了什么但不确定是什么......

-- 更新-- 这是 sqlfiddle:- http://sqlfiddle.com/#!2/a9f45

我的结构:

CREATE TABLE `organisation_classrooms` (
  `classroom_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `active` tinyint(1) NOT NULL,
  `organisation_id` int(11) NOT NULL,
  `period` int(1) DEFAULT '0',
  `classroom_bg` int(2) DEFAULT '3',
  `sortby` varchar(6) NOT NULL DEFAULT 'points',
  `sound` int(1) DEFAULT '0',
  PRIMARY KEY (`classroom_id`)
);

CREATE TABLE organisation_classrooms_myusers (
  `classroom_id` int(11) NOT NULL,
  `user_id` bigint(11) unsigned NOT NULL,
);

CREATE TABLE `classroom_redeemed_codes` (
  `redeemed_code_id` int(11) NOT NULL AUTO_INCREMENT,
  `myuser_id` bigint(11) unsigned NOT NULL DEFAULT '0',
  `ssuser_id` bigint(11) NOT NULL DEFAULT '0',
  `classroom_id` int(11) NOT NULL,
  `order_product_id` int(11) NOT NULL DEFAULT '0',
  `order_product_images_id` int(11) NOT NULL DEFAULT '0',
  `date_redeemed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `points` int(11) NOT NULL,
  `type` int(1) NOT NULL DEFAULT '0',
  `notified` int(1) NOT NULL DEFAULT '0',
  `inactive` tinyint(3) NOT NULL,
   PRIMARY KEY (`redeemed_code_id`),
);

SELECT
  t.classroom_id,
  title,
  COALESCE (
    COUNT(DISTINCT r.redeemed_code_id),
      0
   ) AS totalRewards,
  COALESCE (
    COUNT(DISTINCT ocm.user_id),
    0
   ) AS totalStudents,
  COALESCE (sum(r.points), 0) AS totalPoints
  FROM
  `organisation_classrooms` `t`
   LEFT OUTER JOIN classroom_redeemed_codes r ON (
   r.classroom_id = t.classroom_id
   AND r.inactive = 0
   AND (
    r.date_redeemed >= 1393286400
    OR r.date_redeemed = 0
   )
   )
   LEFT OUTER JOIN organisation_classrooms_myusers ocm ON (
   ocm.classroom_id = t.classroom_id
   )
   WHERE
    t.organisation_id =37383
   GROUP BY title
   ORDER BY t.classroom_id ASC
   LIMIT 10

-- 编辑--

糟糕!有时我讨厌 SQL... 我犯了一个大错误,我试图计算 classroom_redeemed_codes 而不是 organization_classrooms_myuser 表中的学生数量。真的很抱歉我应该早点拿起它?!

classroom_id | totalUniqueStudents
     16             1
     17             2
     46             1
     51             1
     52             1

classroom_redeemed_codes 表中有 7 行,但由于 classroom_id 46 有两行,尽管具有相同的 myuser_id(这是学生 ID),这应该显示为一个唯一的学生。

这有意义吗?本质上是尝试根据 myuser_id 列获取 classroom_redeemed_codes 表中唯一学生的数量。

例如,教室 ID 46 在 classroom_redeemed_codes 表中可能有 100 行,但如果每行的 myuser_id 相同,则应显示 totalUniqueStudents 计数为 1 而不是 100。

如果不清楚请告诉我......

-- 更新-- 我有以下查询似乎从下面的用户那里借来的似乎有效......(我的头很痛)我会再次接受答案。抱歉造成混淆 - 我想我只是想多了

select crc.classroom_id,
    COUNT(DISTINCT crc.myuser_id) AS users,
    COUNT( DISTINCT crc.redeemed_code_id ) AS classRewards,
    SUM( crc.points ) as classPoints, t.title
  from classroom_redeemed_codes crc
       JOIN organisation_classrooms t
         ON crc.classroom_id = t.classroom_id 
        AND t.organisation_id = 37383
        where crc.inactive = 0
        AND ( crc.date_redeemed >= 1393286400
        OR crc.date_redeemed = 0 )
        group by crc.classroom_id

最佳答案

我首先对每个特定类的分数进行预查询聚合,然后使用左连接来运行。我在结果集中获得的行数比您的样本预期的多,但没有 MySQL 可以直接测试/确认。然而here is a SQLFiddle of your query通过使用点的总和进行查询,并在应用用户表时获得笛卡尔结果,它可能是复制点的基础。通过预先查询兑换代码本身,您只需获取该值,然后加入用户。

SELECT
      t.classroom_id,
      title,
      COALESCE ( r.classRewards, 0 ) AS totalRewards,
      COALESCE ( r.classPoints, 0) AS totalPoints,
      COALESCE ( r.uniqStudents, 0 ) as totalUniqRedeemStudents,
      COALESCE ( COUNT(DISTINCT ocm.user_id), 0 ) AS totalStudents
   FROM
      organisation_classrooms t
         LEFT JOIN ( select crc.classroom_id,
                            COUNT( DISTINCT crc.redeemed_code_id ) AS classRewards,
                            COUNT( DISTINCT crc.myuser_id ) as uniqStudents,
                            SUM( crc.points ) as classPoints
                        from classroom_redeemed_codes crc
                           JOIN organisation_classrooms t
                              ON crc.classroom_id = t.classroom_id 
                              AND t.organisation_id = 37383
                        where crc.inactive = 0
                          AND ( crc.date_redeemed >= 1393286400
                           OR crc.date_redeemed = 0 )
                        group by crc.classroom_id ) r
            ON t.classroom_id = r.classroom_id

         LEFT OUTER JOIN organisation_classrooms_myusers ocm 
            ON t.classroom_id = ocm.classroom_id
   WHERE
      t.organisation_id = 37383
   GROUP BY 
      title
   ORDER BY 
      t.classroom_id ASC
   LIMIT 10

关于mysql - 具有多个左连接的查询 - points 列值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27422953/

相关文章:

php - 上传同一个表中的多个文件时出错

mysql - 我不知道/分组依据?有?子查询?我可以用什么?

date - HIVE 在最近的日期左连接

来自子查询的 MySQL 查询不起作用

mysql - 更新(选择...)设置...

mysql - 选择相同城市的用户

android - 安卓应用数据库

mysql - 在 SQL 上索引奇怪的通配符

ios - 如何处理多用户数据库

mysql - 何时在 MySQL 中使用 STRAIGHT_JOIN