【问题标题】:SQL conditional select with for/while loop带有 for/while 循环的 SQL 条件选择
【发布时间】:2017-12-09 11:52:52
【问题描述】:

这是桌子:

Order_ID|Priority|Status 
A       |3       |Normal
A       |4       |Urgent
B       |6       |Urgent
B       |7       |Normal 
C       |8       |Normal
C       |9       |Urgent

如何选择该 ID 的行优先级较高的 Order_ID 和 Status?例如,在这种情况下,给定上述数据的查询的输出应该是:

A - Urgent
B - Normal
C - Urgent

【问题讨论】:

  • 为了将来参考,我建议,对于这些类型的问题,您提供可复制+粘贴的 DDL 和 DML 语句,以激发更好的答案,从而减少创建时间。例如,如果存在唯一约束 (order_id, priority),则解决方案可能比存在唯一约束 (order_id, priority, create_date) 时更容易创建(即,如果存在指示优先级何时更改的 create_date ),或者没有唯一约束。

标签: sql oracle for-loop conditional


【解决方案1】:
select Order_ID || ' - ' || (
    select top 1 Status
    from priorities as p2
    where p1.Order_ID = p2.Order_ID 
    order by p2.Priority desc)
from priorities as p1
group by Order_ID
order by max(Priority)

返回

A - Urgent
B - Normal
C - Urgent

【讨论】:

    【解决方案2】:

    最高优先级的记录 -->> 没有更高优先级的记录


    SELECT *
    FROM order_status o
    WHERE NOT EXISTS(
            SELECT *
            FROM order_status x
            WHERE x.order_id = o.order_id
            AND x.priority > o.priority
            )
            ;
    

    【讨论】:

    • 这需要对表进行两次传递,如果业务任务执行的配置文件在总响应时间的贡献者底部显示此查询,这不会有什么大不了的。跨度>
    • 生成的计划取决于查询计划器/生成器和索引的可用性。
    【解决方案3】:

    一种方法是这样的:

    select order_id || ' - ' || status
    from (
        select order_id, priority, status,
               rank() over (partition by order_id order by priority desc) ranking
        from table
    )
    where ranking = 1;
    

    【讨论】:

    • 我非常喜欢窗口函数。他们使这样的事情变得更容易。对于 OP,还要注意,如果 order_id 具有 2 个相同的最高优先级,此解决方案 (rank()) 将返回多行。
    • @Shawn 这就是为什么我喜欢向 OP 建议这类问题提供可复制+粘贴的 DDL 和 DML 语句,以激发更好的答案,从而减少创建时间。
    【解决方案4】:

    使用 SQL 执行此操作的另一种方法是简单地获取每个 Order_ID 的 MAX(Priority) 并使用 SUBSELECT 连接回该表:

    SELECT  x.ORDER_ID + ' - ' + x.Status AS [Output],
        x.Priority ,
        x.Status
    FROM    ( SELECT    Order_ID AS Order_ID ,
                    MAX(Priority) AS [Priority]
          FROM      @your_table
          GROUP BY ORDER_ID
        ) t
        JOIN @your_table x ON x.Order_ID = t.Order_ID
                           AND x.[Priority] = t.[Priority];
    

    @your_table 是您的表的名称。

    这是查询的输出:

    Output      Priority    Status
    A - Urgent  4           Urgent
    B - Normal  7           Normal
    C - Urgent  9           Urgent
    

    【讨论】:

      猜你喜欢
      • 2015-05-18
      • 2021-01-04
      • 2012-10-20
      • 2014-04-30
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 2014-02-11
      相关资源
      最近更新 更多