请建议如何在Postgres 13.8中实现以下要求,同时返回原始数据的所有行:

CREATE TABLE exam_assessment (
    subject_name varchar(50),
    chapter_name varchar(50),
    chapter_status varchar(50),
    student_id varchar(50),
    marked_status varchar(50));

INSERT INTO exam_assessment 
(subject_name,chapter_name,chapter_status,student_id,marked_status) VALUES
('Science','Chapter1','COMPLETED','6998104_1','Marked as Complete'),
('Science','Chapter2','COMPLETED','6998104_1','Completed'),
('Science','Chapter3','IN_PROGRESS','6998104_1','IN_PROGRESS'),
('Science','Chapter1','COMPLETED','6998103_1','Marked as Complete'),
('Science','Chapter2','COMPLETED','6998103_1','Marked as Complete'),
('Science','Chapter3','COMPLETED','6998103_1','Marked as Complete'),
('Science','Chapter1','COMPLETED','6998102_1','Completed'),
('Science','Chapter2','COMPLETED','6998102_1','Marked as Complete'),
('Science','Chapter3','COMPLETED','6998102_1','Marked as Complete');

Data看起来像这样:

subject_name chapter_name chapter_status student_id marked_status
Science Chapter1 COMPLETED 6998104_1 Marked as Complete
Science Chapter2 COMPLETED 6998104_1 Completed
Science Chapter3 IN_PROGRESS 6998104_1 IN_PROGRESS
Science Chapter1 COMPLETED 6998103_1 Marked as Complete
Science Chapter2 COMPLETED 6998103_1 Marked as Complete
Science Chapter3 COMPLETED 6998103_1 Marked as Complete
Science Chapter1 COMPLETED 6998102_1 Completed
Science Chapter2 COMPLETED 6998102_1 Marked as Complete
Science Chapter3 COMPLETED 6998102_1 Marked as Complete

objective是为了获得学生的整体科目状态:

  • 如果任一章节为IN_PROGRESS,则表示主体状态为IN PROGRESS.
  • 如果所有章节都是Marked as Completed,则主题状态应该是Marked as Completed.
  • 如果所有章节都是Marked as CompletedCompleted的组合,则意味着主体状态应该是Completed.

Examples:

  • 学生6998IN_PROGRESS_1有3章中的marked_status章,IN_PROGRESS-SUBJECT_STATUS应该显示为IN_PROGRESS.
  • 学生6998SUBJECT_STATUS_1在所有章节中都有marked_status,因为Marked as Complete-SUBJECT_STATUS应该显示Marked as Complete.
  • 学生6998COMPLETED_1的3章chapter_status都是COMPLETED,但有些marked_statusMarked as Complete,有些Completed-SUBJECT_STATUS栏应该是Completed.

Expected result:

subject_name chapter_name chapter_status student_id marked_status SUBJECT_STATUS
Science Chapter1 COMPLETED 6998104_1 Marked as Complete IN_PROGRESS
Science Chapter2 COMPLETED 6998104_1 Completed IN_PROGRESS
Science Chapter3 IN_PROGRESS 6998104_1 IN_PROGRESS IN_PROGRESS
Science Chapter1 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter2 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter3 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter1 COMPLETED 6998102_1 Completed Completed
Science Chapter2 COMPLETED 6998102_1 Marked as Complete Completed
Science Chapter3 COMPLETED 6998102_1 Marked as Complete Completed

推荐答案

你可以在case中列出你的规则,在window中你使用every()/bool_and() and bool_or()而不是window,这将它们限制在每个学生的科目章节:demo

select *, case when bool_or(chapter_status='IN_PROGRESS')over w1
               then 'IN_PROGRESS'
               when every(chapter_status='COMPLETED')over w1 and
                    every(marked_status='Marked as Complete')over w1
               then 'Marked as Complete'
               when every(chapter_status='COMPLETED')over w1 and
                    bool_or(marked_status='Completed')over w1
               then 'Completed' 
          end as "SUBJECT_STATUS"
from exam_assessment
window w1 as (partition by subject_name,student_id)
order by student_id desc, chapter_name asc;
subject_name chapter_name chapter_status student_id marked_status SUBJECT_STATUS
Science Chapter1 COMPLETED 6998104_1 Marked as Complete IN_PROGRESS
Science Chapter2 COMPLETED 6998104_1 Completed IN_PROGRESS
Science Chapter3 IN_PROGRESS 6998104_1 IN_PROGRESS IN_PROGRESS
Science Chapter1 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter2 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter3 COMPLETED 6998103_1 Marked as Complete Marked as Complete
Science Chapter1 COMPLETED 6998102_1 Completed Completed
Science Chapter2 COMPLETED 6998102_1 Marked as Complete Completed
Science Chapter3 COMPLETED 6998102_1 Marked as Complete Completed

Postgresql相关问答推荐

使函数内部动态插入更具可读性

select语句的Jooq代码生成

仅使用 ssl 连接到 Postgresql 数据库

INSERT 语句返回策略违规(USING 表达式)

在 postgres/presto/AWS-Athena 中,与 array_agg( (col1, col2) ) 相反的是什么来获得每组多行?

Postgres数据库系统已准备好接受连接和docker compose

至少 pgRouting 的某些部分可以与并行查询并行运行吗?

有没有办法使用postgresql将具有不同ID的同一行多次添加到表中?

无法从在 wsl 2 上运行的服务之一连接到在 wsl 2 上的容器中运行的 postgres 数据库

如何防止 PDO 将问号解释为占位符?

Django 1.8 数组字段追加和扩展

如何向文本字段添加长度约束

在 PostgreSQL docker 镜像中创建表

gem install pg 无法绑定到 libpq

PostgreSQL:如何安装 plpythonu 扩展

Postgres 删除表语法错误

PGError:错误: column of relation does not exist

Oracle 相当于 Postgres 的 DISTINCT ON?

当从 Heroku pg:pull 数据库时提示:role "root" does not exist.

Ecto Postgres 安装错误密码验证失败