【问题标题】:sql query to find priority jobssql查询查找优先作业
【发布时间】:2021-06-01 06:55:00
【问题描述】:

我有一个名为 x 的 sql 表

|priority     |CategoryType |status       |CategoryGroup|
|-------------|-------------|-------------|-------------|
|7            |NoFeedBF     |ready        |NoFeed|
|5            |FeedWIL      |ready        |Feed|
|6            |FeedSIL      |ready        |Feed|
|7            |NoFeedDRM    |ready        |NoFeed|
|8            |NoFeedFx     |processing   |NoFeed|
|9            |NoFeedHK     |             |NoFeed|
|10           |Common       |ready        |Common|

我想根据优先级、类别组和状态检索行的位置

当有工作出现时,它会来到这张桌子并将其标记为准备就绪。 每当收到作业时,它会将状态标记为处理中

规则如下:

  1. no feed 和 feed 不应一起运行
  2. 如果处于就绪状态,common 可以同时使用 feed 和 nofeed 运行
  3. 如果状态已就绪,则必须选择优先级最高的作业(例如 common 和 nofeedhk)
  4. 如果 NoFeed 正在处理(例如 NoFeedFx),则必须从同一类别组(NoFeed)中提取处于就绪状态的最高优先级作业(例如 common 和 NoFeedDRM、NoFeedBF)
  5. 如果 Feed 处于处理状态(例如 FeedWIL),它可以从同一类别组(Feed)中获取另一个新的 Feed,如果处于就绪状态且具有最高优先级(例如 Common 和 FeedSIL)

尝试制定查询,但无法为所有场景找到成功的查询(例如包括相同优先级的常见和多条记录等)

select category_type, priority,status, category_group from x where category_group in  
(select distinct category_group from x 
where status = 
(select distinct case 
when (select count(status) from x where status='processing')>=1 then 'processing'
when (select count(status) from x where status='processing')<1 then 'ready'
else null
end "status"
from x)) 
and upper(status) IN ('READY','PROCESSING') 
order by priority asc fetch first 1 rows only;

如果您可以形成更好的查询以匹配规则,请提供帮助。非常感谢

示例 1:

priority CategoryType status CategoryGroup
7 NoFeedBF ready NoFeed
5 FeedWIL ready Feed
6 FeedSIL ready Feed
7 NoFeedDRM ready NoFeed
8 NoFeedFx ready NoFeed
9 NoFeedHK NoFeed
10 Common ready Common

Outputexpected-1(参见规则 3)

priority CategoryType status CategoryGroup
10 Common ready Common
8 NoFeedFx ready NoFeed

示例 2:

priority CategoryType status CategoryGroup
7 NoFeedBF ready NoFeed
5 FeedWIL ready Feed
6 FeedSIL ready Feed
7 NoFeedDRM running NoFeed
8 NoFeedFx ready NoFeed
9 NoFeedHK NoFeed
10 Common ready Common

输出预期(见规则 4)

priority CategoryType status CategoryGroup
10 Common ready Common
8 NoFeedFx ready NoFeed

示例 3:

priority CategoryType status CategoryGroup
7 NoFeedBF ready NoFeed
5 FeedWIL ready Feed
6 FeedSIL ready Feed
7 NoFeedDRM ready NoFeed
6 NoFeedADHOC running NoFeed
8 NoFeedFx NoFeed
9 NoFeedHK NoFeed
10 Common ready Common

输出预期(见规则 4)

priority CategoryType status CategoryGroup
10 Common ready Common
7 NoFeedBF ready NoFeed
7 NoFeedDRM ready NoFeed

示例 4:

priority CategoryType status CategoryGroup
7 NoFeedBF ready NoFeed
5 FeedWIL running Feed
6 FeedSIL ready Feed
7 NoFeedDRM ready NoFeed
6 NoFeedADHOC ready NoFeed
8 NoFeedFx ready NoFeed
9 NoFeedHK NoFeed
10 Common ready Common

输出预期(参见规则 5)

priority CategoryType status CategoryGroup
10 Common ready Common
6 FeedSIL ready Feed

【问题讨论】:

  • 根据您的数据,您的预期输出是什么?
  • 左对齐 SQL 很难读,也很难写。
  • @Jaime Drq 输出是基于优先级的记录,类别组正在运行。它基于我上面提到的规则。感谢您提供的帮助
  • @Prasath,我的意思是您是否可以根据您的样本数据(手动)提供预期的输出
  • @Jaime Drq 谢谢。当不同的场景/规则到位时,我已经给出了示例和预期的输出。

标签: sql database oracle


【解决方案1】:

这是您可以做到的一种方法 - 请注意,我已经模仿了您的表格,其中包含所有不同的输入集,而您的实际表格没有,因此您必须修改查询以删除对example_no 列的引用。

我添加了第 5 种情况,即 NoFeed 和 Feed 具有相同优先级的就绪任务;我选择 NoFeed 比 Feed 具有更高的优先级,所以我只显示该类别。如果您需要更改它以显示 Feed 任务或同时显示两个任务,则需要修改 dense_rank 中的 order by 子句。

WITH your_table AS (SELECT 1 example_no, 7 priority, 'NoFeedBF' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 5 priority, 'FeedWIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 6 priority, 'FeedSIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 7 priority, 'NoFeedDRM' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 8 priority, 'NoFeedFx' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 9 priority, 'NoFeedHK' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 1 example_no, 10 priority, 'Common' CategoryType, 'ready' status, 'Common' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 7 priority, 'NoFeedBF' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 5 priority, 'FeedWIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 6 priority, 'FeedSIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 7 priority, 'NoFeedDRM' CategoryType, 'running' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 8 priority, 'NoFeedFx' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 9 priority, 'NoFeedHK' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 2 example_no, 10 priority, 'Common' CategoryType, 'ready' status, 'Common' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 7 priority, 'NoFeedBF' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 5 priority, 'FeedWIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 6 priority, 'FeedSIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 7 priority, 'NoFeedDRM' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 6 priority, 'NoFeedADHOC' CategoryType, 'running' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 8 priority, 'NoFeedFx' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 9 priority, 'NoFeedHK' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 3 example_no, 10 priority, 'Common' CategoryType, 'ready' status, 'Common' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 7 priority, 'NoFeedBF' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 5 priority, 'FeedWIL' CategoryType, 'running' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 6 priority, 'FeedSIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 7 priority, 'NoFeedDRM' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 6 priority, 'NoFeedADHOC' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 8 priority, 'NoFeedFx' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 9 priority, 'NoFeedHK' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 4 example_no, 10 priority, 'Common' CategoryType, 'ready' status, 'Common' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 7 priority, 'NoFeedBF' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 8 priority, 'FeedWIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 6 priority, 'FeedSIL' CategoryType, 'ready' status, 'Feed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 7 priority, 'NoFeedDRM' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 8 priority, 'NoFeedFx' CategoryType, 'ready' status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 9 priority, 'NoFeedHK' CategoryType, NULL status, 'NoFeed' CategoryGroup FROM dual UNION ALL
                    SELECT 5 example_no, 10 priority, 'Common' CategoryType, 'ready' status, 'Common' CategoryGroup FROM dual),
   curr_running AS (SELECT example_no,
                           priority,
                           categorytype,
                           status,
                           categorygroup,
                           nofeed_running,
                           feed_running,
                           CASE WHEN categorygroup = 'NoFeed' AND feed_running = 1 THEN NULL
                                WHEN categorygroup = 'Feed' AND nofeed_running = 1 THEN NULL
                                ELSE categorygroup
                           END new_categorygroup
                    FROM   (SELECT example_no,
                                   priority,
                                   categorytype,
                                   status,
                                   categorygroup,
                                   MAX(CASE WHEN categorygroup = 'NoFeed' AND status = 'running' THEN 1 END) OVER (PARTITION BY example_no) nofeed_running,
                                   MAX(CASE WHEN categorygroup = 'Feed' AND status = 'running' THEN 1 END) OVER (PARTITION BY example_no) feed_running
                            FROM   your_table
                            WHERE  status IN ('ready', 'running'))),
        results AS (SELECT example_no,
                           priority,
                           categorytype,
                           status,
                           categorygroup,
                           new_categorygroup,
                           nofeed_running,
                           feed_running,
                           dense_rank() OVER (PARTITION BY example_no, CASE WHEN new_categorygroup IN ('NoFeed', 'Feed') THEN 'Feed' ELSE new_categorygroup END ORDER BY priority DESC, new_categorygroup DESC) dr
                    FROM   curr_running
                    WHERE  status = 'ready'
                    AND    new_categorygroup IS NOT NULL)
SELECT example_no,
       priority,
       categorytype,
       status,
       categorygroup
FROM   results
WHERE  dr = 1
ORDER BY example_no,
         dr,
         categorytype;

EXAMPLE_NO   PRIORITY CATEGORYTYPE STATUS  CATEGORYGROUP
---------- ---------- ------------ ------- -------------
         1         10 Common       ready   Common
         1          8 NoFeedFx     ready   NoFeed
         2         10 Common       ready   Common
         2          8 NoFeedFx     ready   NoFeed
         3         10 Common       ready   Common
         3          7 NoFeedBF     ready   NoFeed
         3          7 NoFeedDRM    ready   NoFeed
         4         10 Common       ready   Common
         4          6 FeedSIL      ready   Feed
         5         10 Common       ready   Common
         5          8 NoFeedFx     ready   NoFeed

这通过使用MAX 分析函数来确定Feed 和NoFeed 类别的每组数据中是否已经存在正在运行的任务,然后使用它来输出类别组列的新版本,其中类别对于我们不想与其他组中的任务同时运行的组,设置为 null。

一旦我们获得了这些信息,我们就会执行 dense_rank 以找到我们感兴趣的每个类别具有最高密集排名的就绪行。

最后,我们只选择dense_rank 为1 的那些行——即最高优先级的行。

【讨论】:

  • 非常感谢 Boneist。只需一次更正,对于您创建的多个条目,总会有一个共同的工作。如果普通作业准备好了,那么它将与饲料一起被挑选,或者没有饲料。如果普通的工作没有准备好,那么它不应该被挑选。
  • 我只将您的多组示例合并到一个数据集中,因此我只需更改一个查询,而不必将更改反映到多个其他查询,我可以看到这些更改对所有查询的影响立即举例。如果您注意到,每个 example_no 值只有 1 个“通用”任务。正如我在答案顶部已经说过的那样,您不需要在实际表中执行此操作,但是当您尝试确保查询涵盖所有场景时,您可能希望这样做。当然,这确实意味着您必须在对查询感到满意后对其进行调整!
猜你喜欢
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多