【问题标题】:When using DISTINCT the COUNT (*) OVER() does not return the correct number使用 DISTINCT 时,COUNT (*) OVER() 不会返回正确的数字
【发布时间】:2021-08-31 11:11:16
【问题描述】:

我有一个类似的问题,但这次我使用更复杂的查询来描述我的问题......

我只是想知道在 Postgresql 中选择连接的多行查询时是否有一种简单的方法来获得不同的计数(我使用限制和偏移进行分页,但在这种情况下它可能不太重要)。

例如,我有这些表

学生桌:

id name
1 Student1
2 Student2
3 Student3

教师桌:

id name
1 Teacher1
1 Teacher2

student_teacher 表:

id studentId teacherId
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2

课桌:

id name
1 Classroom1
2 Classroom2
3 Classroom3

teacher_classoom 表:

id teacherId classroomId
1 1 1
2 1 2
3 2 3

这是我当前的 sql 查询:

SELECT DISTINCT(student.*), COUNT(*) OVER() AS "total_count" from student
JOIN student_teacher on student_teacher.studentId = student.id
JOIN teacher on student_teacher.teacherId = teacher.id
JOIN teacher_classroom on teacher_classroom.teacherId = teacher.id
JOIN classroom on classroom.id = teacher_classroom.classroomId 
LIMIT 10 OFFSET 0

“total_count”将是 9 而不是 3(连接查询后不同学生的数量),即使结果只有 3 行。如果没有“distinct”关键字,则结果有 9 行。

有没有一种简单的方法可以实现 total_count = 3?任何帮助将不胜感激。

【问题讨论】:

  • 实现什么的简单方法?你想让total_count 是 3,而不是 9?请明确说明您的目标。最清晰的方法是发布您现在获得的数据集,以及您想要的数据集。
  • @Nick.McDermaid 是的,达到 total_count = 3.. 我已经编辑了问题..

标签: postgresql


【解决方案1】:

DISTINCT是在窗口函数之后计算的,所以你必须使用子查询:

SELECT *, COUNT(*) OVER() AS "total_count"
FROM (SELECT DISTINCT student.*
      from student
         JOIN student_teacher on student_teacher.studentId = student.id
         JOIN teacher on student_teacher.teacherId = teacher.id
         JOIN teacher_classroom on teacher_classroom.teacherId = teacher.id
         JOIN classroom on classroom.id = teacher_classroom.classroomId
    ) AS subq
LIMIT 10 OFFSET 0;

将内部连接和DISTINCT 转换为一系列EXISTS 条件会更有效。

【讨论】:

  • 这正是我想要做的.. 我没有意识到在窗口函数之后完成了 distinct.. 我认为现在使用子查询应该没问题.. 感谢您的帮助
  • 显然对于获取大量数据的更复杂的查询,使用子查询非常慢......您认为使用 EXISTS 会提高性能吗?目前我正在使用一个通用函数,它基本上执行 SELECT *, COUNT( * ) OVER() AS "total_count" FROM (${sql}) AS subq LIMIT 10 OFFSET 0;
  • 查询中的联接和DISTINCT 仅用于检查其他表中是否存在与学生匹配的行。 EXISTS 会更有效率,特别是因为DISTINCT 很贵。
猜你喜欢
  • 2019-10-22
  • 2012-06-27
  • 2016-01-14
  • 2014-12-08
  • 1970-01-01
  • 2014-07-04
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
相关资源
最近更新 更多