【问题标题】:double JOIN and GROUP on hasMany associationshasMany 关联上的双重 JOIN 和 GROUP
【发布时间】:2013-02-17 23:25:36
【问题描述】:

我有 3 个模型(表):

Presentation hasMany PresentationView hasMany SlideView

字段:

演示文稿:id, title

演示视图:id, presentation_id

幻灯片视图:id, presentation_view_id, duration

我需要一个查询来获取每个演示文稿的统计信息。统计数据是:

  1. 每个 Presentation 的 PresentationView 数量
  2. 属于 Presentation 的幻灯片视图中所有 SlideView.duration 的总持续时间(通过 PresentationView)

所以基本上它看起来像是双重 JOIN 和双重 GROUP,但连接对我不起作用 - 我尝试了 LEFT/INNER/RIGHT 双连接的每种组合,但我无法使其工作。我所拥有的最好的是 Presentation 已对 PresentationView 进行分组,但持续时间仅来自 SlideViews 的 SUMed,该 SlideViews 仅属于一个 PresentationViews 而不是全部用于 Presentation...

如果可能,我想避免嵌套 SELECT。只需加入/组

【问题讨论】:

  • 如果您能弄清楚究竟什么以及以什么方式不适合您,这将有所帮助。您可以使用您尝试过的至少一些连接组合(实际查询)来更新您的问题。这也可以说明您在尝试中可能出错的地方。

标签: mysql sql


【解决方案1】:

首先是一个简单的 JOIN 和 COUNT:

SELECT p.id, COUNT(*)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
GROUP BY p.id

第二个必须使用 SUM(和 JOIN):

SELECT p.id, SUM(s.duration)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
JOIN SlideView s ON v.id = s.presentation_view_id
GROUP BY p.id

如果您想在一个查询中同时使用两者:

SELECT p.id, SUM(s.duration), COUNT(DISTINCT v.id)
FROM Presentation p
JOIN PresentationView v ON p.id = v.presentation_id
JOIN SlideView s ON v.id = s.presentation_view_id
GROUP BY p.id

DISTINCT的原因:

表格:

Presentation:    PresentationView:          SlideView:
p.id | title     v.id | presentation_id     s.id | presentation_view_id | duration
1    | abc       1    | 1                   1    | 1                    | 100
2    | xyz       2    | 1                   2    | 1                    | 150
                 3    | 1                   3    | 2                    | 200
                 4    | 1                   4    | 2                    | 250
                 5    | 1                   5    | 3                    | 300
                 6    | 2                   6    | 3                    | 400
                 7    | 2                   7    | 4                    | 500
                                            8    | 5                    | 600
                                            9    | 6                    | 100
                                            10   | 6                    | 200
                                            11   | 7                    | 350

组之前的示例结果集:

p.id | v.id | s.id | s.duration
-------------------------------
1    | 1    | 1    | 100
1    | 1    | 2    | 150
1    | 2    | 3    | 200
1    | 2    | 4    | 250
1    | 3    | 5    | 300
1    | 3    | 6    | 400
1    | 4    | 7    | 500
1    | 5    | 8    | 600
2    | 6    | 9    | 100
2    | 6    | 10   | 200
2    | 7    | 11   | 350

在没有不同的组之后:

p.id | SUM | COUNT
------------------
1    | 8   | 2500
2    | 3   | 650

有区别:

p.id | SUM | COUNT
------------------
1    | 5   | 2500
2    | 2   | 650

【讨论】:

  • 嘿 - 你的答案很好,但你在 COUNT 中缺少 DISTINCT -> 看看我的答案
【解决方案2】:

同时我找到了答案:

SELECT presentations.title, SUM(slide_views.duration), COUNT(DISTINCT presentation_views.id) 
FROM presentations 
LEFT JOIN presentation_views ON presentations.id = presentation_views.presentation_id 
LEFT JOIN slide_views ON presentation_views.id = slide_views.presentation_view_id 
GROUP BY presentations.id

【讨论】:

  • 这个DISTINCT 毫无意义,因为 id 是主键,并且本质上必须是不同的。 ..或者也许..让我考虑一下
  • 现在我确定了 :D 你是对的。但前提是你加入所有三个表!示例:1 个演示文稿有 4 个视图,这 4 个视图各有 2 张幻灯片。所以group by presentation.id之后每个presentation_view.id都会出现两次。
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-06
  • 2015-12-04
相关资源
最近更新 更多