【问题标题】:Oracle SQL select highest values from different tables with "in line view"Oracle SQL 使用“行内视图”从不同表中选择最高值
【发布时间】:2015-09-16 14:56:16
【问题描述】:

我有一个数据库,其中包含两个表“prod_group”和“product”中的产品信息。有 4 个不同的产品组包含多个产品。我应该使用“在线视图”来选择每个产品组中最昂贵的产品。

我目前的代码:

select *
from
(
select distinct pg.group_name, p.price most_expensive
from prod_group pg, product p
where pg.group_id = p.group_id
group by pg.group_name, p.price
order by p.price desc
)
where rownum < 5;

上述代码的问题在于,即使我使用“distinct”,打印出来的 4 个产品也是整个数据库中最昂贵的 4 个产品,而不是 4 个产品组中最贵的。

【问题讨论】:

    标签: oracle inline highest


    【解决方案1】:
    select  pg.group_name, max(p.price) 
    from prod_group pg, product p
    where pg.group_id = p.group_id
    group by pg.group_name
    order by pg.group_name
    

    SQLFiddle

    【讨论】:

    • 感谢这个非常干净的解决方案!
    • 呃,我看不出这是如何选择每组最昂贵的产品(或任何产品)。我也没有看到任何内联视图。
    【解决方案2】:

    这将获得每个组名最昂贵的价格:

    select group_name,
           price AS most_expensive
    from
    (
      select pg.group_name,
             p.price,
             ROW_NUMBER() OVER ( PARTITION BY pg.group_name ORDER BY p.price DESC ) AS rn
      from   prod_group pg
             INNER JOIN
             product p
             ON ( pg.group_id = p.group_id )
    )
    where rn = 1;
    

    【讨论】:

      【解决方案3】:

      SQL 是关于什么 数据获取,而不是如何 获取它。因此,要求使用特定技术编写查询的情况并不常见。所以我猜是老师问你这个?但是后来:您使用的是二十多年前被替换的旧连接语法。我想,现在没有老师会教你了。

      嗯,内联视图是现在通常称为派生表的旧Oracle名称,即FROM子句中的子查询。使用派生表编写查询是一个奇怪的请求,因为您可以将任何查询转换为这样的格式:select * from (&lt;some query here&gt;)

      您被要求获得其产品组中价格最高的产品。有两个表,但所需的所有数据(产品及其组)都可以在其中一个表 product 中找到。无需从另一个表 prod_group 中进行选择。典型的直接查询是:

      select *
      from product where (group_id, price) in
      (
        select group_id, max(price)
        from product
        group by group_id
      );
      

      虽然这不使用派生表,但可以使用上面给出的方法重写。但是,我们可以将IN 子句替换为连接,然后我们可以更自然地得到派生表:

      select p.*
      from product p
      join 
      (
        select group_id, max(price) as price
        from product
        group by group_id
      ) pmax on pmax.group_id = p.group_id and pmax.price = p.price;
      

      另一种方法是使用解析MAX 函数,这也可以避免必须从同一个表中选择两次:

      select *
      from
      (
        select 
          p.*,
          max(price) over (partition by group_id) as maxprice
        from product p
      )  
      where price = maxprice;
      

      这里我们甚至需要派生表,因为我们不能将分析函数放在我们想要的WHERE 子句中。我们必须在子查询中使用它,并将条件放在外部查询中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-01
        • 1970-01-01
        • 2017-04-13
        • 1970-01-01
        • 2017-05-29
        • 1970-01-01
        • 2018-10-25
        • 2020-05-14
        相关资源
        最近更新 更多