sql - 比较oracle中的多行和多列
问题描述
我正在使用 Oracle SQL,假设我有一个像这样的表,其中包含项目各个阶段的开始日期和完成日期。
项目编号 | 阶段 | 开始日期 | 完成日期 |
---|---|---|---|
PROJ_001 | 1 | 21 年 3 月 12 日 | 21 年 3 月 12 日 |
PROJ_001 | 2 | 21 年 3 月 14 日 | 21 年 3 月 14 日 |
PROJ_001 | 3 | 21 年 3 月 15 日 | 21 年 3 月 15 日 |
PROJ_001 | 4 | 21 年 3 月 18 日 | 21 年 3 月 18 日 |
PROJ_002 | 1 | 21 年 3 月 16 日 | 21 年 3 月 18 日 |
PROJ_002 | 2 | 21 年 3 月 17 日 | 21 年 3 月 19 日 |
PROJ_002 | 3 | 21 年 3 月 19 日 | 21 年 3 月 19 日 |
PROJ_002 | 4 | 21-MAR-21 | 21 年 3 月 23 日 |
我需要将输出如下表所示。对于阶段级输出,需要比较完成日期和开始日期;对于项目级,需要检查项目的最后阶段(即阶段 4)
项目编号 | 阶段 | 开始日期 | 完成日期 | 输出 1 | 输出 2 项目级别 |
---|---|---|---|---|---|
PROJ_001 | 1 | 21 年 3 月 12 日 | 21 年 3 月 12 日 | 准时 | 准时 |
PROJ_001 | 2 | 21 年 3 月 14 日 | 21 年 3 月 14 日 | 准时 | 准时 |
PROJ_001 | 3 | 21 年 3 月 15 日 | 21 年 3 月 15 日 | 准时 | 准时 |
PROJ_001 | 4 | 21 年 3 月 18 日 | 21 年 3 月 18 日 | 准时 | 准时 |
PROJ_002 | 1 | 21 年 3 月 16 日 | 21 年 3 月 18 日 | 延迟 | 延迟 |
PROJ_002 | 2 | 21 年 3 月 17 日 | 21 年 3 月 19 日 | 延迟 | 延迟 |
PROJ_002 | 3 | 21 年 3 月 19 日 | 21 年 3 月 19 日 | 准时 | 延迟 |
PROJ_002 | 4 | 21-MAR-21 | 21 年 3 月 23 日 | 延迟 | 延迟 |
谁能帮我?
解决方案
您可以编写 2 个查询,{Q1} 返回“输出 1”所需的值,{2} 为您提供“输出 2”的值。一旦你看到这些查询产生了正确的结果,就将它们连接在一起。示例参见DBfiddle。
查询 1(“阶段级别”)
select
projectno, stages, startdate, completiondate
, case
when startdate = completiondate then 'on time'
else 'delayed'
end output_1
from projects;
查询 2(“项目级别”)
-- look at the last stage (only). CASE may need tweaking
select
projectno
, case
when max( startdate ) = max( completiondate ) then 'on time'
else 'delayed'
end output_2
from projects
group by projectno
;
加入
select Q1.*, Q2.output_2
from (
select
projectno, stages, startdate, completiondate
, case
when startdate = completiondate then 'on time'
else 'delayed'
end output_1
from projects
) Q1 join (
select
projectno
, case
when max( startdate ) = max( completiondate ) then 'on time'
else 'delayed'
end output_2
from projects
group by projectno
) Q2 on Q1.projectno = Q2.projectno
order by Q1.projectno, Q1.startdate
;
-- result
PROJECTNO STAGES STARTDATE COMPLETIONDATE OUTPUT_1 OUTPUT_2
PROJ_001 1 12-MAR-21 12-MAR-21 on time on time
PROJ_001 2 14-MAR-21 14-MAR-21 on time on time
PROJ_001 3 15-MAR-21 15-MAR-21 on time on time
PROJ_001 4 18-MAR-21 18-MAR-21 on time on time
PROJ_002 1 16-MAR-21 18-MAR-21 delayed delayed
PROJ_002 2 17-MAR-21 19-MAR-21 delayed delayed
PROJ_002 3 19-MAR-21 19-MAR-21 on time delayed
PROJ_002 4 21-MAR-21 23-MAR-21 delayed delayed
附录
(采纳@Thorsten Kettner 的建议:)您还可以使用 max() 以分析函数的形式,例如
-- remove the comments -> see the output of max(...) over (...)
select
projectno, stages, startdate, completiondate
, case
when startdate = completiondate then 'on time'
else 'delayed'
end output_1
, case
when
max( startdate ) over ( partition by projectno )
= max( completiondate ) over ( partition by projectno )
then 'on time'
else 'delayed'
end output_2
-- , max( startdate ) over ( partition by projectno ) maxstart_
-- , max( completiondate ) over ( partition by projectno ) maxcompletion_
from projects;
推荐阅读
- javascript - Javascript switch 语句给了我一个错误。到底是怎么回事?
- javascript - 基于滚动向单个 div 添加/删除类,每个 div 都有自己独特的类
- azure-devops - 如何让 Azure DevOps 为 .net 标准 2.0 项目创建正确的 nuspec?
- python - 调用第二组多线程函数
- spring-kafka - 使用 Spring Boot 2.1.12 和 Spring for Apache Kafka 2.2.12 进行 JUnit 测试
- gatsby - 部署的 Netlify 页面在显示实际内容之前显示 404 页面
- arrays - 为什么 PowerShell 创建字符数组而不是字符串数组?
- reactjs - 在 react-test-renderer 测试中渲染 jest 快照之前运行 useEffect 钩子
- vb.net - 通过分隔符插入每个数字
- r - 使用 Geom_Point(color) 时从 ggplot(scatterplot) 中删除结果