按月查找值的总和然后找到最大的月数总和
find sum of values by month then find max sum of months
我需要找到每个月的值总和,然后找到月份的最大值。我有点难过,不知道该怎么办。
My customer wants it formatted a particular way:
Activity | JUN | JUL | AUG | MIN | MAX | AVG
jogging | 232 | 32 | 343 | 32 | 343 | 202
Here is my table:
activity + status + date
____________________________
swimming + 1 + 13-DEC-02
swimming + 1 + 12-FEB-01
jogging + 0 + 14-AUG-03
这是我目前的情况:
SELECT ACTIVITY,
SUM(
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'JUL','JUL') IN 'JUL'
THEN 1
ELSE 0
END ) JUL,
SUM(
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'AUG','AUG') IN 'AUG'
THEN 1
ELSE 0
END ) AUG
FROM daily_log
WHERE ACTIVITY_DESC IN ('Swimming','Jogging')
AND TRUNC(date) BETWEEN '01-JUL-2014' AND '30-JUN-2015'
AND STATUS = 1
group by ACTIVITY
求助!
对于 MIN/MAX,您可以使用 GREATEST 和 LEAST,如果您只需要 result.O 中的 select 值,则可以使用 MIN、MAX 和 AVG 函数来聚合这些值直接来自源数据。
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm
您可能还想研究使用子查询,尤其是使用 WITH 子句。您可以将 select 个中间结果组合在一起。
http://oracle-base.com/articles/misc/with-clause.php
关于 SUM(CASE 位,您可以访问 PIVOT 作为将行转换为列的选项。
http://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1.php
编辑:
应该这样做
SELECT Activity,
COALESCE(AUG,0) AS AUG,
COALESCE(JUN,0) AS JUN,
COALESCE(JUL,0) AS JUL,
MIN,MAX,AVG
FROM (
SELECT
Mon,
Activity,
Count,
MIN(Count) OVER (PARTITION BY Activity) AS Min,
MAX(Count) OVER (PARTITION BY Activity) AS Max,
AVG(Count) OVER (PARTITION BY Activity) AS Avg
FROM (
SELECT TO_CHAR("date",'MON') AS Mon, activity, COUNT(*) Count
FROM daily_log
GROUP BY TO_CHAR("date",'MON'), activity
)
) PIVOT ( SUM(Count) FOR Mon IN ('AUG' AS AUG, 'JUN' AS JUN, 'JUL' AS JUL))
您的查询有点太复杂了。例如:
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'AUG','AUG') IN 'AUG'
THEN 1
ELSE 0
END
可以重写为:
CASE WHEN TO_CHAR(date, 'MON') = 'AUG' THEN 1 ELSE 0 END
甚至:
DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)
换句话说,您需要 CASE
或 DECODE()
,但不能同时需要两者。考虑到这一点,我们可以稍微重写您的查询:
SELECT activity
, SUM(DECODE(TO_CHAR(date, 'MON'), 'JUL', 1, 0)) AS jul
, SUM(DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)) AS aug
FROM daily_log
WHERE activity_desc IN ('Swimming','Jogging')
AND date >= DATE'2014-07-01'
AND date < DATE'2015-07-01'
AND status = 1
GROUP BY activity;
现在,请注意我是如何更改 date
列上的过滤器的(顺便说一下,这是一个糟糕的列名称,因为 DATE
是一个 Oracle 关键字,用于数据类型和 ANSI 日期文字)。您希望避免在 DATE
列上使用 TRUNC()
,尤其是在它已被索引时(如果未被索引,您可能需要考虑对其进行索引)。由于您需要所有月份的最小值和最大值,因此您需要使用 LEAST()
和 GREATEST()
函数:
SELECT activity, jul, aug
, LEAST(jul, aug) AS min
, GREATEST(jul, aug) AS max
, (jul+aug)/2 AS avg
FROM (
SELECT activity
, SUM(DECODE(TO_CHAR(date, 'MON'), 'JUL', 1, 0)) AS jul
, SUM(DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)) AS aug
FROM daily_log
WHERE activity_desc IN ('Swimming','Jogging')
AND date >= DATE'2014-07-01'
AND date < DATE'2015-07-01'
AND status = 1
GROUP BY activity
);
不幸的是,LEAST()
和 GREATEST()
无法计算平均值,因此我们必须手动计算。添加额外月份的结果时,您需要增加分母。
您想要聚合两次:一次计算每月汇总,第二次计算这些汇总的统计信息。这需要(至少)两个查询,一个在另一个范围内作为公共 table 表达式、内联视图或子查询。例如:
SELECT
activity,
SUM(
CASE month
WHEN 7 THEN count
ELSE 0
END
) JUL,
SUM(
CASE month
WHEN 8 THEN count
ELSE 0
END
) AUG,
AVG(count) AS avg,
MAX(count) AS max
FROM (
SELECT
activity,
EXTRACT(MONTH FROM "date") AS month,
COUNT(*) AS count
FROM daily_log
WHERE
ACTIVITY_DESC IN ('Swimming','Jogging')
AND TRUNC("date") BETWEEN '01-JUL-2014' AND '30-JUN-2015'
AND STATUS = 1
group by ACTIVITY, EXTRACT(MONTH FROM "date")
)
GROUP BY activity
请注意,在您的 真实 查询中,您可能希望比 AVG(count)
更聪明,否则如果平均值为零,您将得到错误的平均值一个或多个月内感兴趣的条目。
我需要找到每个月的值总和,然后找到月份的最大值。我有点难过,不知道该怎么办。
My customer wants it formatted a particular way:
Activity | JUN | JUL | AUG | MIN | MAX | AVG
jogging | 232 | 32 | 343 | 32 | 343 | 202
Here is my table:
activity + status + date
____________________________
swimming + 1 + 13-DEC-02
swimming + 1 + 12-FEB-01
jogging + 0 + 14-AUG-03
这是我目前的情况:
SELECT ACTIVITY,
SUM(
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'JUL','JUL') IN 'JUL'
THEN 1
ELSE 0
END ) JUL,
SUM(
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'AUG','AUG') IN 'AUG'
THEN 1
ELSE 0
END ) AUG
FROM daily_log
WHERE ACTIVITY_DESC IN ('Swimming','Jogging')
AND TRUNC(date) BETWEEN '01-JUL-2014' AND '30-JUN-2015'
AND STATUS = 1
group by ACTIVITY
求助!
对于 MIN/MAX,您可以使用 GREATEST 和 LEAST,如果您只需要 result.O 中的 select 值,则可以使用 MIN、MAX 和 AVG 函数来聚合这些值直接来自源数据。
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm
您可能还想研究使用子查询,尤其是使用 WITH 子句。您可以将 select 个中间结果组合在一起。
http://oracle-base.com/articles/misc/with-clause.php
关于 SUM(CASE 位,您可以访问 PIVOT 作为将行转换为列的选项。
http://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1.php
编辑: 应该这样做
SELECT Activity,
COALESCE(AUG,0) AS AUG,
COALESCE(JUN,0) AS JUN,
COALESCE(JUL,0) AS JUL,
MIN,MAX,AVG
FROM (
SELECT
Mon,
Activity,
Count,
MIN(Count) OVER (PARTITION BY Activity) AS Min,
MAX(Count) OVER (PARTITION BY Activity) AS Max,
AVG(Count) OVER (PARTITION BY Activity) AS Avg
FROM (
SELECT TO_CHAR("date",'MON') AS Mon, activity, COUNT(*) Count
FROM daily_log
GROUP BY TO_CHAR("date",'MON'), activity
)
) PIVOT ( SUM(Count) FOR Mon IN ('AUG' AS AUG, 'JUN' AS JUN, 'JUL' AS JUL))
您的查询有点太复杂了。例如:
CASE
WHEN DECODE(TO_CHAR((TRUNC(date)), 'MON'),'AUG','AUG') IN 'AUG'
THEN 1
ELSE 0
END
可以重写为:
CASE WHEN TO_CHAR(date, 'MON') = 'AUG' THEN 1 ELSE 0 END
甚至:
DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)
换句话说,您需要 CASE
或 DECODE()
,但不能同时需要两者。考虑到这一点,我们可以稍微重写您的查询:
SELECT activity
, SUM(DECODE(TO_CHAR(date, 'MON'), 'JUL', 1, 0)) AS jul
, SUM(DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)) AS aug
FROM daily_log
WHERE activity_desc IN ('Swimming','Jogging')
AND date >= DATE'2014-07-01'
AND date < DATE'2015-07-01'
AND status = 1
GROUP BY activity;
现在,请注意我是如何更改 date
列上的过滤器的(顺便说一下,这是一个糟糕的列名称,因为 DATE
是一个 Oracle 关键字,用于数据类型和 ANSI 日期文字)。您希望避免在 DATE
列上使用 TRUNC()
,尤其是在它已被索引时(如果未被索引,您可能需要考虑对其进行索引)。由于您需要所有月份的最小值和最大值,因此您需要使用 LEAST()
和 GREATEST()
函数:
SELECT activity, jul, aug
, LEAST(jul, aug) AS min
, GREATEST(jul, aug) AS max
, (jul+aug)/2 AS avg
FROM (
SELECT activity
, SUM(DECODE(TO_CHAR(date, 'MON'), 'JUL', 1, 0)) AS jul
, SUM(DECODE(TO_CHAR(date, 'MON'), 'AUG', 1, 0)) AS aug
FROM daily_log
WHERE activity_desc IN ('Swimming','Jogging')
AND date >= DATE'2014-07-01'
AND date < DATE'2015-07-01'
AND status = 1
GROUP BY activity
);
不幸的是,LEAST()
和 GREATEST()
无法计算平均值,因此我们必须手动计算。添加额外月份的结果时,您需要增加分母。
您想要聚合两次:一次计算每月汇总,第二次计算这些汇总的统计信息。这需要(至少)两个查询,一个在另一个范围内作为公共 table 表达式、内联视图或子查询。例如:
SELECT
activity,
SUM(
CASE month
WHEN 7 THEN count
ELSE 0
END
) JUL,
SUM(
CASE month
WHEN 8 THEN count
ELSE 0
END
) AUG,
AVG(count) AS avg,
MAX(count) AS max
FROM (
SELECT
activity,
EXTRACT(MONTH FROM "date") AS month,
COUNT(*) AS count
FROM daily_log
WHERE
ACTIVITY_DESC IN ('Swimming','Jogging')
AND TRUNC("date") BETWEEN '01-JUL-2014' AND '30-JUN-2015'
AND STATUS = 1
group by ACTIVITY, EXTRACT(MONTH FROM "date")
)
GROUP BY activity
请注意,在您的 真实 查询中,您可能希望比 AVG(count)
更聪明,否则如果平均值为零,您将得到错误的平均值一个或多个月内感兴趣的条目。