SQL查询:选择subselect的最大值

时间:2016-01-05 10:18:50

标签: sql oracle subquery

我有一个已经有效的sql语句,但我认为必须有一个比我更好的解决方案。

我正在尝试获取 最高价格 最高价 从未被销售。< / p>

通过这个选择,我得到了尚未售出的所有文章(数字+价格):

select anr, price
from article a 
where not exists(
    select 1 from OrderItems o
    where o.artnr = a.anr 
  )

商品编号+价格结果如下

| Anr | Price |
| 1   | 300.0 |
| 4   | 340.0 |
| 5   | 340.0 |
| 3   | 200.0 |

我获得价格最高的文章的临时解决方案是:

select anr, price 
from article 
where anr in(
  select anr
  from article a 
  where not exists(
    select 1 from OrderItems o
    where o.artnr = a.anr 
  )
)
and price = (
  select max(price)
  from article a 
  where not exists(
    select 1 from OrderItems o
    where o.artnr = a.anr 
  )
)

正确的解决方案是:

| Anr | Price |
| 4   | 340.0 |
| 5   | 340.0 |

有没有办法避免两次使用相同的subselect?

这里的测试是使用我的插入值缩短的Create Table脚本:

CREATE TABLE Article
(
  Anr Int Primary Key,
  Price Numeric(9,2) Not Null
);

CREATE TABLE Orders
(
  OrderNr Int Primary Key
)

CREATE TABLE OrderItems
(
  OrderNr Int References Orders On Delete Cascade, 
  ItemNr  Int,
  Artnr   Int References Article Not Null,
  Amount  Int Not Null Check(Amount >= 0),
  Primary Key(OrderNr, ItemNr)
)

-- articles without an order
Insert into Article (Anr, Price) values(1,300.0);
Insert into Article (Anr, Price) values(4,340.0);
Insert into Article (Anr, Price) values(5,340.0);
Insert into Article (Anr, Price) values(3,200.0);

-- articles for order with orderNr '1'
Insert into Article (Anr, Price) values(2,340.0);
Insert into Article (Anr, Price) values(6,620.0);

-- insert test order that contains the two articles
Insert into Orders (OrderNr) values (1);
Insert into OrderItems(OrderNr, ItemNr, Artnr, Amount) values(1,1,2,4);
Insert into OrderItems(OrderNr, ItemNr, Artnr, Amount) values(1,2,6,2);

我还阅读了主题Select max value in subquery SQL 但我认为在我的情况下必须有一个较短的方式来进行选择。

3 个答案:

答案 0 :(得分:2)

这是一个解决方案,可以避免使用其中一个相关子查询,而是将其替换为LEFT JOIN

SELECT a.*
FROM article a LEFT JOIN OrderItems o ON a.anr = o.artnr
WHERE o.artnr IS NULL AND
    a.price = (SELECT MAX(a.price)
               FROM article a LEFT JOIN OrderItems o ON a.anr = o.artnr
               WHERE o.artnr IS NULL)

此解决方案应符合ANSI-92标准,这意味着它应该与MySQL,Oracle,SQL Server以及您可能遇到的任何其他类型的快餐都很友好。

答案 1 :(得分:0)

/usr/bin/php -f 'path_to_php_script.php'

试试这个......

答案 2 :(得分:-1)

您可以将原始查询与窗口函数一起使用以获得所需内容:

select anr, price
from (
    select anr, price, max(price) over () as max_price
    from article a 
    where not exists (select 1 
                      from OrderItems o
                      where o.artnr = a.anr)
) t
where price = max_price;

可能更快,因为只需要对article表进行一次扫描。

或者你可以使用左连接解决方​​案来查找从未订购过的文章,但如果Oracle为此使用不同的执行计划,我会感到惊讶:

select anr, price
from (
    select anr, price, max(price) over () as max_price
    from article a 
      left join OrderItems o ON o.artnr = a.anr
    where o.artnr is null
) t
where price = max_price;

SQLFiddle示例:http://sqlfiddle.com/#!15/1eb69/1