【问题标题】:joining one table to multi others将一张桌子连接到多张桌子
【发布时间】:2019-04-01 00:41:42
【问题描述】:
i have 3 tables as the following:

学生

---------------
id     name
---------------
1      Joe
2      mark
3      mike
---------------

主题

-----------------------------------
id    student_id    name
-----------------------------------
1         1          math
2         1          english
3         1          french
4         1          history
5         2          math
6         2          english
7         2          french
8         3          math
9         3          english
-----------------------------------

考试

-----------------------------------
ID  Student_id   mark
-----------------------------------
1    1           10
2    1           10
3    1           10
4    1           10
5    2           5
6    2           5
7    2           5
8    3           2
9    3           2
-----------------------------------
SELECT
    student.id, student.name AS 'NAME',
    COUNT(subject.id) AS 'SUBJECTS',
    SUM(exam.mark) AS 'MARKS'
FROM
    'student'
INNER JOIN subject
ON   subject.student_id = student.id

LEFT JOIN exam
ON exam.student_id = student.id
GROUP BY
    student.id

我想加入 STUDENT 和 SUBJECT、STUDENT 和 EXAM 当我加入第三张桌子时,我的问题正在发生,它
复制结果。

我成功加入了前两个表,但是当我加入 > 第三个表时,它会重复计数。

我需要的结果是:

----------------------------------- 
ID       NAME     SUBJECTS     MARKS 
----------------------------------- 
1         joe        4          40
2         mark       3          15
3         mike       2           4

【问题讨论】:

  • 您如何确定哪个mark 是针对哪个主题的?
  • 我只需要学生的总分,而不是每个科目的总分@PaulSpiegel
  • 这不是我问的。如果您认为这种关系无关紧要 - 祝您好运!你可能会需要它。
  • 我的cmets的原因:dbfiddle.uk/…

标签: mysql


【解决方案1】:

这里的一种简单方法是对subjectexam 表进行单独的聚合,然后将它们连接起来:

SELECT
    s.id,
    s.name AS NAME,
    COALESCE(su.cnt, 0) AS SUBJECTs,
    COALESCE(e.marks, 0) AS MARKS
FROM student s
LEFT JOIN
(
    SELECT student_id, COUNT(*) AS cnt
    FROM subject
    GROUP BY student_id
) su
    ON s.id = su.student_id
LEFT JOIN
(
    SELECT student_id, SUM(mark) AS marks
    FROM exam
    GROUP BY student_id
) e
    ON s.id = e.student_id;

Demo

请注意,我在上面使用了左连接,因为给定的学生可能在subjectexam 表中根本没有任何条目。在这种情况下,我们会默认将他的计数/总和分配为零。

【讨论】:

  • 工作正常,您是否建议任何 pdf 或课程来学习此 sql 语句,谢谢@Tim Biegeleisn
  • SQL 与大多数语言一样,需要大量练习才能掌握。像我上面所做的那样,简单地获得抽象的放手知识可能无法教出一个查询。
  • 你能提供同样的 laravel ORM 风格的代码吗? @蒂姆·比格莱森
  • 不,我不能在这里这样做,但您的跟进可能是另一个问题的主题。
【解决方案2】:

您可以通过对每个学生 ID 使用直接查询来获取聚合列:

select 
  s.id, s.name,
  (select count(*) from subject where student_id = s.id) subjects,
  (select sum(mark) from exam where student_id = s.id) marks
from student s

请参阅demo

【讨论】:

  • 你能提供同样的 laravel ORM 风格的代码吗? @forpas
猜你喜欢
  • 2012-05-23
  • 2014-10-14
  • 2017-02-07
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-09
  • 2020-07-29
相关资源
最近更新 更多