简体   繁体   English

Oracle SQL:从组中选择一个最大值和最小值

[英]Oracle SQL: Select a Max and Min Value from a Group

From multiple tables I'm currently selecting a product, value, and contract period. 我目前正在从多个表中选择产品,价值和合同期限。 I want to group the results by product and shipment period while summing the value. 我想按产品和装运期对结果进行分组,同时对值求和。

My contract period can either be arrival based or shipment based. 我的合同期限可以是到货或发货。 So, currently to determine which contract period to use, I'm looking to see if one of the period descriptions is null then populating the period end and begin dates as either ship or arrival based on that. 因此,当前要确定要使用的合同期限,我希望查看其中一个期限说明是否为空,然后根据该日期填充期限结束并以发货或到达日期作为开始日期。 Specifically, I'm using the following. 具体来说,我正在使用以下内容。

DECODE((P.SHIP_PERIOD_DESCR), NULL, 
'ARRIVE'  || ' '  ||P.ARRIVAL_PERIOD_BEGIN || ' - '  || P.ARRIVAL_PERIOD_END, 
'SHIP'  || ' '  ||P.SHIP_PERIOD_BEGIN || ' - '  || P.SHIP_PERIOD_END)

My results are as such: 我的结果是这样的:

PRODUCT     VALUE      CONTRACT_PERIOD
APPLES      $600        SHIP 01-FEB-16 - 15-MAR-16
APPLES      $700        SHIP 01-MAR-16 - 15-APR-16
LEMONS      $200        SHIP 15-JAN-16 - 31-JAN-16
LEMONS      $150        SHIP 01-FEB-16 - 15-FEB-16
LEMONS      $200        ARRIVE 15-FEB-16 - 28-FEB-16
LEMONS      $250        ARRIVE 01-MAR-16 - 15-MAR-16

What I would like to see is the min ship or arrival date and max ship or arrival date per product as such: 我想看到的是每种产品的最低出货或到货日期以及最高出货或到货日期,例如:

PRODUCT     VALUE      CONTRACT_PERIOD
APPLES      $1,300      SHIP 01-FEB-16 - 15-APR-16
LEMONS      $350        SHIP 15-JAN-16 - 15-FEB-16
LEMONS      $450        ARRIVE 15-FEB-16 - 15-MAR-16

Any suggestions on a way to determine which contract is valid, then group the results using the min and max dates while not interchanging a ship date for an arrival date would be greatly appreciated. 我们将不胜感激有关确定哪种合同有效,然后使用最小和最大日期对结果进行分组而不将发货日期与到达日期互换的方式的任何建议。

The basic idea is not to combine the different columns into a single concatenated column. 基本思想不是将不同的列合并为单个串联的列。 Then use intelligent aggregation: 然后使用智能聚合:

with t as (
      <basically your query here, but with each column individually>
     )
select product, ship_period_desc,
       min(case when ship_period_desc = 'ARRIVAL' then ARRIVAL_PERIOD_BEGIN
                else SHIP_PERIOD_BEGIN
           end) as PERIOD_BEGIN,
       min(case when ship_period_desc = 'ARRIVAL' then ARRIVAL_PERIOD_END
                else SHIP_PERIOD_END
           end) as PERIOD_END
from t
where ship_period_desc in ('ARRIVAL', 'SHIP')
group by product, ship_period_desc;

Oracle Setup : Oracle安装程序

CREATE TABLE table_name ( product, value, ship_period_descr, arrival_period_begin, arrival_period_end, ship_period_begin, ship_period_end ) AS
SELECT 'Apples', 600, 'X', NULL, NULL, DATE '2016-02-01', DATE '2016-03-15' FROM DUAL UNION ALL
SELECT 'Apples', 700, 'X', NULL, NULL, DATE '2016-03-01', DATE '2016-04-16' FROM DUAL UNION ALL
SELECT 'Lemons', 200, 'X', NULL, NULL, DATE '2016-01-15', DATE '2016-01-31' FROM DUAL UNION ALL
SELECT 'Lemons', 150, 'X', NULL, NULL, DATE '2016-02-01', DATE '2016-02-15' FROM DUAL UNION ALL
SELECT 'Lemons', 200, NULL, DATE '2016-02-15', DATE '2016-02-28', NULL, NULL FROM DUAL UNION ALL
SELECT 'Lemons', 250, NULL, DATE '2016-03-01', DATE '2016-03-15', NULL, NULL FROM DUAL;

Query : 查询

SELECT   Product,
         SUM( Value ) AS Value,
         DECODE(
           DECODE( P.SHIP_PERIOD_DESCR, NULL, 1, 0 ),
           1, 'ARRIVE ' || MIN( P.ARRIVAL_PERIOD_BEGIN ) || ' - ' || MAX( P.ARRIVAL_PERIOD_END ),
              'SHIP ' || MIN( P.SHIP_PERIOD_BEGIN ) || ' - ' || MAX( P.SHIP_PERIOD_END )
         ) AS Contract_Period
FROM     table_name p
GROUP BY Product,
         DECODE( P.SHIP_PERIOD_DESCR, NULL, 1, 0 );

Results : 结果

PRODUCT      VALUE CONTRACT_PERIOD                              
------- ---------- ----------------------------------------------
Apples        1300 SHIP 01-FEB-16 - 16-APR-16                     
Lemons         350 SHIP 15-JAN-16 - 15-FEB-16                     
Lemons         450 ARRIVE 15-FEB-16 - 15-MAR-16                   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM