Oracle SQL:从不同的行中选择最小值和最大值

时间:2014-01-03 10:19:04

标签: sql oracle select

我有一个看起来像这样的表(每个Date-Item最多2行):

    Date        Item Price
    -----------------------
    20140101    A     100
    20140101    A     200
    20140101    B     50
    20140101    B     70
    20140102    A     20
    20140102    A     40
    20140102    B     10
    20140102    B     60

如何在一行中获得每个日期 - 项目对的最高和最低价格,如下所示?

可能只有一个价格(一行)的Date_Items。对于这些对,我希望将该价格设置为Min_Price,将NULL设置为Max_Price。

    Date        Item Min_Price  Max_Price
    --------------------------------------
    20140101    A     100      200
    20140101    B     50       70
    20140102    A     20       40
    20140102    B     10       60

2 个答案:

答案 0 :(得分:2)

以这种方式试试

SELECT "Date", item, MIN(price) min_price, 
       CASE WHEN MIN(price) = MAX(price) THEN NULL ELSE MAX(price) END max_price
  FROM table1
 GROUP BY "Date", item
 ORDER BY "Date", item

SELECT "Date", item, MIN(price) min_price,
        CASE WHEN COUNT(*) = 1 THEN NULL ELSE MAX(price) END max_price
  FROM table1
 GROUP BY "Date", item
 ORDER BY "Date", item

取决于您在同一天如何处理场景,如果可能的话,您有两行具有相同的价格。

输出:

|                           DATE | ITEM | MIN_PRICE | MAX_PRICE |
|--------------------------------|------|-----------|-----------|
| January, 01 2014 00:00:00+0000 |    A |       100 |       200 |
| January, 01 2014 00:00:00+0000 |    B |        50 |        70 |
| January, 02 2014 00:00:00+0000 |    A |        20 |        40 |
| January, 02 2014 00:00:00+0000 |    B |        10 |        60 |

这是 SQLFiddle 演示

答案 1 :(得分:1)

此类查询的关键是GROUP BY子句。当您使用这样的子句时,您为每个要分组的列的唯一值生成一行。这意味着查询的选择列表可能只包含每个组具有单个值的表达式 - 来自选择列表本身的项目或聚合函数。

一旦获得此主要权限,null - date组合的item值与单个条目相同,则可以使用case表达式进行处理:

SELECT date, item, 
       min_price,
       CASE WHEN cnt > 1 THEN max_price ELSE NULL END AS max_price
FROM   (SELECT   date, item, 
                 COUNT(*) AS cnt, MIN(price) AS min_price, MAX(price) AS max_price
        FROM     mytable
        GROUP BY date, item) t