Oracle SQL 按字符串聚合字段分组
Oracle SQL Group By a String Aggregated Field
我在对查询中的字段进行分组时遇到问题。这是我正在谈论的示例:
示例:
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;
感谢您的提前帮助!
根据您的示例数据,这应该可以满足您的要求:
select AIR_DT, DOL_GAP_TIME, sum(MATL_SIZE)
from table t
group by AIR_DT, DOL_GAP_TIME;
但是,我不知道这与问题中的查询有什么关系。
好的,让我们开始您的初始查询:
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
获取时间的方式真的很奇怪。看起来你想向下舍入到小时,然后只得到小时加上它是 AM 还是 PM。所以这个:
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
我在对查询中的字段进行分组时遇到问题。这是我正在谈论的示例:
示例:
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;
感谢您的提前帮助!
根据您的示例数据,这应该可以满足您的要求:
select AIR_DT, DOL_GAP_TIME, sum(MATL_SIZE)
from table t
group by AIR_DT, DOL_GAP_TIME;
但是,我不知道这与问题中的查询有什么关系。
好的,让我们开始您的初始查询:
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
获取时间的方式真的很奇怪。看起来你想向下舍入到小时,然后只得到小时加上它是 AM 还是 PM。所以这个:
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