最少按不同分组 - SQL

Posted

技术标签:

【中文标题】最少按不同分组 - SQL【英文标题】:Fewest grouped by distinct - SQL 【发布时间】:2016-02-17 14:33:45 【问题描述】:

好的,我认为这个问题的答案在某个地方,但我找不到它...... (甚至我的标题都不好)

简而言之,我想从关联表的一部分中获得最少数量的组


第一,请记住,这已经是 5 个表(+1k 行)加入过滤器和分组的结果,我将不得不在像香蕉一样强大的 prod 服务器上运行很多次。 ..

2nd,这是一个假的案例,说明你我的问题


经过一些查询,我得到了这个数据结果:

+--------------------+
|id_course|id_teacher|
+--------------------+
|    6    |    1     |
|    6    |    4     |
|    6    |    14    |
|   33    |    1     |
|   33    |    4     |
|   34    |    1     |
|   34    |    4     |
|   34    |    10    |
+--------------------+

如您所见,我有 3 门课程,最多由 3 位老师教授。我需要参加每一门课程,但我希望尽可能少的不同老师(我很害羞......)。

我的第一个查询

应该回答:每门独特的课程我需要的最少教师人数是多少?

有了这个数据,它就是1,因为教师 1 或教师 4 为这 3 人制作课程。


第二次查询

现在我已经获得了这些课程,我想参加另外两门课程,3250,时间表如下:

+--------------------+
|id_course|id_teacher|
+--------------------+
|   32    |    1     |
|   32    |    12    |
|   50    |    12    |
+--------------------+

我的问题是:对于 id_course N,我需要多找一位老师吗?

我想逐门查看,所以“查看32门课程”,不需要同时查看多个

我认为最好的方法是使用第一个查询中排名最低的教师列表来计算内部连接,因此我们的数据只有两个:Teacher(1, 4)

对于课程32,Teacher2 不做这个,但作为Teacher1 做Courses(6, 33, 34, 32),我不必再找另一个老师。

对于课程50,唯一的老师是Teacher12,所以我找不到我选择的老师,我必须再找一个(所以总共有两个数据)


这是一个基础 [SQLFiddle

最好的问候,布拉格

【问题讨论】:

【参考方案1】:

您想获得一个不同的 ID_Teachers 计数,然后......获得一个不同的计数并将结果限制为 1 条记录。

所以也许像......

SELECT count(Distinct ID_Teacher), Group_concat(ID_Teacher) as TeachersIDs
FROM  Table
WHERE ID_Course in ('Your List')
ORDER BY count(Distinct ID_Teacher) ASC Limit 1

但是,如果存在平局,这将随机选择...所以您是否要提供选项来选择应该存在平局的教师组和班级?这意味着有多种途径可以完成涉及相同数量教师的所有课程……例如,教师 A、B 和 A、C 完成所有必需的课程……这两个记录应该在结果中返回还是 1 就足够了?

【讨论】:

this 回复我4 而不是我想要的1;我需要为每门课程找一位老师,我试图找出是否有一位老师教我需要的每门课程 这就像解决“每门独特的课程我需要的最少教师人数是多少?” 有趣我现在明白了……还在考虑中。 是的,我通常不擅长 SQL,但这两个有点棘手,从 2 天开始我就一直坚持下去(正如我所说,我不会向你展示后面的 5 个表加入以获得这个非常小的数据集 XD);我想我已经找到了一种使用子查询、分组和加入的方法,但是如果我恢复大脑,我明天会看到/测试这个......【参考方案2】:

所以我终于找到了一种方法来做我想做的事!

对于第一个查询,由于我潜在的真正需求是“是否有一个老师可以做所有事情”,所以我降低了一些期望并选择了这个(我的真实案例 u_u 为 58 行):

SELECT
    (
        SELECT count(s.id_teacher) nb
        FROM t AS m
        INNER JOIN t AS s
            ON m.id_teacher = s.id_teacher
        GROUP BY m.id_course, m.id_teacher
        ORDER BY nb DESC
        LIMIT 1
        ) AS nbMaxBySingleTeacher,
    (
        SELECT COUNT(DISTINCT id_course) nb
        FROM t
        ) AS nbTotalCourseToDo

[SQLFiddle

我得到了两个值来回答我的问题“一位老师就够了吗?”

+--------------------------------------+
|nbMaxBySingleTeacher|nbTotalCourseToDo|
+--------------------------------------+
|         4          |        5        |
+--------------------------------------+

第二个查询使用新课程的时间表,并获取我要检查的课程的 id。它应该告诉我是否需要再找一位老师,或者我的实际老师是否可以。

SELECT COUNT(*) nb
FROM (
    SELECT
        z.id_teacher
    FROM z
    WHERE
        z.id_course = 50
    ) t1
WHERE
    FIND_IN_SET(t1.id_teacher, (
        SELECT GROUP_CONCAT(t2.id_teacher) lst
        FROM (
            SELECT DISTINCT COUNT(s.id_teacher) nb, m.id_teacher
            FROM t AS m
            INNER JOIN t AS s
                ON m.id_teacher = s.id_teacher
            GROUP BY m.id_course, m.id_teacher
            ORDER BY nb DESC
            ) t2
        GROUP BY t2.nb
        ORDER BY nb DESC
        LIMIT 1
        ));

[SQLFiddle

这告诉我有多少老师能够教授我已有的课程以及我想要的新课程。所以如果超过零,那我就不需要新老师了:

+--+
|nb|
+--+
|1 |
+--+

【讨论】:

以上是关于最少按不同分组 - SQL的主要内容,如果未能解决你的问题,请参考以下文章

SQL:在选择不同行时按一个字段中的最小值分组

用于计数和显示(列中的不同值)的 Sql 查询优化,按其他两列分组

按格式化字符串分组的 SQL 联合

sql: 按 x,y,z 分组;返回按 f(z) 最低的 x,y 分组

SQL - 如何将按类别分组的指标值展平为单行?

按语句分组 SQL