【问题标题】:How to efficiently evaluate rows and sub records in single PL/SQL如何在单个 PL/SQL 中有效地评估行和子记录
【发布时间】:2015-08-25 19:39:19
【问题描述】:

我正在努力编写 PL/SQL(我是 PL/SQL 新手),我不确定如何为这样的东西构建 SQL 和循环。

我有 128 行 SQL 来创建类似以下光标的内容:

ID   Course   Grade Attend? Date
123  MATH091  B     Y       5/15
123  BIOL101  F     N       3/10
123  ENGL201  W     Y       1/2
456  MATH091  A     Y       5/16
456  CHEM101  C     Y       5/16
456  POLS301  NULL  NULL    NULL

对于每个 ID,我需要对课程进行多次比较(例如,哪些课程的日期最晚,或者所有课程都参加过)。这些比较需要按照一定的顺序进行,这样当它们命中一个为真时,就会用代码标记它们并从后续比较中排除。

例如:

  • 所有课程都参加了吗?如果为 true,则输出为 attended 并从后续步骤中删除。
  • 查找并存储通过成绩的最新日期。
  • 查找并存储未及格分数的最新日期。
  • 是否是零成绩课程之后的日期?如果为 true,则输出为 coming back 并从后续步骤中删除。

每个条件都可以很容易地用 SQL 编写,但我不知道/理解循环这个过程的适当结构。

有没有语法可以轻松做到这一点?

我们使用的是 Oracle 11g,我们没有写入临时表的权限。

【问题讨论】:

  • 我不确定我是否理解这个问题。我的猜测是,您可以使用一两个分析函数大大简化 SQL 语句。但是,如果您想从 SQL 迁移到 PL/SQL,我不确定您到底在寻找什么。您显然可以在 PL/SQL 中使用for 循环,尽管我不确定您要循环什么。您可能希望构建一个流水线表函数来返回结果。

标签: oracle plsql oracle11g


【解决方案1】:

我认为您不需要为此使用 PL/SQL。除了“未知”要求“等”。这一切都可以在一条 SQL 语句中完成:

类似:

select id, course, grade, attended, attendance_date, 
       count(distinct case when attended = 'Y' then course end) over (partition by id) courses_attended,
       count(distinct course) over () as total_courses,
       case
          when count(distinct case when attended = 'Y' then course end) over (partition by id) = count(distinct course) over () then 'yes'
          else 'no'
       end as all_courses_attended,
       max(case when attended <> 'F' then attendance_date else null end) over (partition by id) as latest_passing_date,
       max(case when attended = 'F' then attendance_date else null end) over (partition by id) as latest_non_passing_date
from attendees
order by id;

顺便说一句:如果您有attendance_date,则不需要attended 列。如果该日期不为 NULL,则显然该学生参加了该课程。否则她/他没有。

当然我不知道“等”是什么。步骤应该做......

SQLFiddle 示例:http://sqlfiddle.com/#!4/e7c95/1

【讨论】:

  • 我没有意识到这种级别的逻辑仅在 SQL 中可用。这正是我所需要的,这对于未来的 SQL 也将非常方便。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2011-04-08
  • 2011-04-12
  • 2010-12-25
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多