Oracle字符串聚合字段的Oracle SQL组

时间:2015-03-05 02:41:57

标签: sql oracle oracle11g group-by oracle-sqldeveloper

我在查询中对字段进行分组时出现问题。以下是我所说的一个例子:

示例:

AIR_DT             DOL_GAP_TIME         MATL_SIZE                     
15-JAN-15          8:00 AM              30
15-JAN-15          8:00 AM              25
15-JAN-15          9:00 AM              5
15-JAN-15          9:00 AM              10
15-JAN-15          9:00 AM              5
15-JAN-15          9:00 AM              20

那些有相同时间的人应该归为一,总结他们的matl_size

预期产出:

AIR_DT             DOL_GAP_TIME         MATL_SIZE                     
15-JAN-15          8:00 AM              55
15-JAN-15          9:00 AM              40

这是我的SQL:

SELECT 
      a.air_dt, 
      TRIM(SUBSTR(TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss AM'),12,2))
      || ':00 '
      || TRIM(SUBSTR (TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss    AM'),
21, 2)) dol_gap_time, e.matl_size
FROM order_implem_dtl_broadcast a, matl_mstr b, matl_size_mstr e 
WHERE a.matl_id = b.matl_id 
AND b.matl_size_id = e.matl_size_id  
AND a.air_dt LIKE '%15-JAN-15%'
GROUP BY a.air_dt, a.dol_pref_start_time, e.matl_size
ORDER BY a.air_dt, a.dol_pref_start_time;

感谢您提前帮助!

2 个答案:

答案 0 :(得分:2)

根据您的示例数据,这应该符合您的要求:

select AIR_DT, DOL_GAP_TIME, sum(MATL_SIZE)
from table t
group by AIR_DT, DOL_GAP_TIME;

但是,我不知道这与问题中的查询有什么关系。

答案 1 :(得分:1)

好的,让我们从您的初始查询开始:

SELECT 
  a.air_dt, 
  TRIM(SUBSTR(TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss AM'),12,2))
  || ':00 '
  || TRIM(SUBSTR (TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss    AM'), 21, 2)) dol_gap_time, e.matl_size
  FROM order_implem_dtl_broadcast a, matl_mstr b, matl_size_mstr e 
 WHERE a.matl_id = b.matl_id 
   AND b.matl_size_id = e.matl_size_id  
   AND a.air_dt LIKE '%15-JAN-15%'
 GROUP BY a.air_dt, a.dol_pref_start_time, e.matl_size
 ORDER BY a.air_dt, a.dol_pref_start_time;

我看到了几个问题。其一,您按e.matl_size进行分组,即使这是您要SUM()的列。你不希望它出现在GROUP BY中。其次,你从dol_pref_start_time获得时间的方式真的很奇怪。看起来你想要向下舍入到小时,然后只是得到小时加上是上午还是下午。所以这个:

TRIM(SUBSTR(TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss AM'),12,2))
  || ':00 '
  || TRIM(SUBSTR (TO_CHAR (a.dol_pref_start_time, 'mm/dd/yyyy hh:mi:ss    AM'), 21, 2)) dol_gap_time

就是这样:

TO_CHAR(TRUNC(a.dol_pref_start_time, 'HH'), 'HH:MI AM') AS dol_gap_time

第三,您的日期是否存储为日期?如果是这样,你为什么要这样做?

AND a.air_dt LIKE '%15-JAN-15%'

这样做会好得多:

AND TRUNC(a.air_dt) = date'2015-01-15'

或者,如果您在a.air_dt上有索引,则:

AND a.air_dt >= date'2015-01-15'
AND a.air_dt < date'2015-01-16'

总而言之,我们得到类似的结果(请注意,我还将您的连接转换为ANSI SQL连接):

SELECT TRUNC(a.air_dt) AS air_dt
     , TO_CHAR(TRUNC(a.dol_pref_start_time, 'HH'), 'HH:MI AM') AS dol_gap_time
     , SUM(e.matl_size) AS matl_size
  FROM order_implem_dtl_broadcast a INNER JOIN matl_mstr b
    ON a.matl_id = b.matl_id
 INNER JOIN matl_size_mstr e 
    ON b.matl_size_id = e.matl_size_id
 WHERE a.air_dt >= date'2015-01-15'
   AND a.air_dt < date'2015-01-16'
 GROUP BY TRUNC(a.air_dt), TO_CHAR(TRUNC(a.dol_pref_start_time, 'HH'), 'HH:MI AM')
 ORDER BY air_dt, TO_DATE(dol_gap_time, 'HH:MI AM'); -- using aliases in the ORDER BY, converting dol_gap_time to DATE for sorting