简体   繁体   English

如何在Oracle中按日期分组和排序?

[英]How to group by date and sort in Oracle?

I run this SQL request:我运行这个 SQL 请求:

SELECT Max(scaleA.val) AS scaleA_val,
       Max(scaleB.val) AS scaleB_val,
       To_char(From_dt1970(scaleA.time1970), 'DD') AS day
  FROM rsdu2elarh.el008_6305119 scaleA
  FULL OUTER JOIN rsdu2elarh.el008_6305126 scaleB
    ON scaleA.time1970 = scaleB.time1970
 WHERE scaleA.time1970 > To_dt1970(To_date('2019/11/01', 'yyyy/mm/dd'))
   AND scaleA.time1970 < To_dt1970(To_date('2019/12/01', 'yyyy/mm/dd'))
 GROUP BY 'day'
 ORDER BY 'day'

and return it:并返回:

在此处输入图片说明

But it is not sorted by date.但它不是按日期排序的。 How to make the request display data sorted by date?如何让请求显示按日期排序的数据? All my attempts result in "not a group by expression" or many repeated fields :(我所有的尝试都导致“不是按表达式分组”或许多重复的字段:(

If you use GROUP BY clause, any expression in SELECT or ORDER BY, which is not group function (or aggregate function or aggregated column) such as COUNT, AVG, MIN, MAX, SUM and so on (List of Aggregate functions) should be present in GROUP BY clause.如果使用 GROUP BY 子句,则 SELECT 或 ORDER BY 中的任何表达式,它不是组函数(或聚合函数或聚合列),如 COUNT、AVG、MIN、MAX、SUM 等(聚合函数列表)应为存在于 GROUP BY 子句中。

Example 1: (here employee_id is not group function , so it must appear in GROUP BY. By contrast, sum(salary) is a group function (aggregated column), so it is not required to appear in the GROUP BYclause.例1:(这里employee_id不是分组函数,所以必须出现在GROUP BY中。相比之下,sum(salary)是分组函数(聚合列),所以不需要出现在GROUP BY子句中。

SELECT employee_id, sum(salary) 
FROM employees
GROUP BY employee_id
ORDER BY employee_id; 

Example 2: This will lead to the "not a group by expression" error .示例 2:这将导致“not a group by expression”错误。

SELECT employee_id, sum(salary) 
FROM employees;  

To correct you need to do one of the following :要更正,您需要执行以下操作之一:

Include all non-aggregated expressions listed in SELECT and ORDER BY clause in the GROUP BY clause.将 SELECT 和 ORDER BY 子句中列出的所有非聚合表达式包含在 GROUP BY 子句中。

You can not order by with the column which is not groupped because same date may appear in more than one group so if you want order by DD then you can use it in order by clause as following:您不能使用未分组的列进行排序,因为相同的日期可能出现在多个组中,因此如果您想按DD排序,则可以在order by子句中使用它,如下所示:

SELECT  MAX(scaleA.VAL) AS scaleA_val, MAX(scaleB.VAL) AS scaleB_val FROM RSDU2ELARH.EL008_6305119 scaleA 
FULL OUTER JOIN RSDU2ELARH.EL008_6305126 scaleB ON scaleA.time1970 = scaleB.time1970 
WHERE scaleA.time1970 > TO_DT1970(TO_DATE ('2019/11/01', 'yyyy/mm/dd')) AND scaleA.time1970 < TO_DT1970(TO_DATE ('2019/12/01', 'yyyy/mm/dd')) 
GROUP BY TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD')
-- use this order by clause
Order by TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD')

Cheers!!干杯!!

You can try to add TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD') also into the SELECT list, alias it and use within ORDER BY Clause :您可以尝试将TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD')也添加到 SELECT 列表中,将其别名并在 ORDER BY Clause 中使用:

SELECT TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD') AS myDay,
       MAX(scaleA.VAL) AS scaleA_val, 
       MAX(scaleB.VAL) AS scaleB_val
  FROM RSDU2ELARH.EL008_6305119 scaleA
  FULL OUTER JOIN RSDU2ELARH.EL008_6305126 scaleB
    ON scaleA.time1970 = scaleB.time1970
 WHERE scaleA.time1970 > TO_DT1970(DATE'2019-11-01')
   AND scaleA.time1970 < TO_DT1970(DATE'2019-12-01')
 GROUP BY TO_CHAR(FROM_DT1970(scaleA.time1970), 'DD')
 ORDER BY myDay

while column alias cannot be used for GROUP BY Clause.而列别名不能用于 GROUP BY 子句。

The only missing thing in your query is that we cannot use an alias in the group by clause, but alias can be used in order by clause so below query will work.您的查询中唯一缺少的是我们不能在 group by 子句中使用别名,但是可以在 order by 子句中使用别名,因此下面的查询将起作用。

SELECT Max(scaleA.val) AS scaleA_val,
       Max(scaleB.val) AS scaleB_val,
       To_char(From_dt1970(scaleA.time1970), 'DD') AS day
  FROM rsdu2elarh.el008_6305119 scaleA
  FULL OUTER JOIN rsdu2elarh.el008_6305126 scaleB
    ON scaleA.time1970 = scaleB.time1970
 WHERE scaleA.time1970 > To_dt1970(To_date('2019/11/01', 'yyyy/mm/dd'))
   AND scaleA.time1970 < To_dt1970(To_date('2019/12/01', 'yyyy/mm/dd'))
 GROUP BY To_char(From_dt1970(scaleA.time1970), 'DD')
 ORDER BY day;

If You want to use an alias then you need to use a subquery如果要使用别名,则需要使用子查询

SELECT Max(scaleA_val)  AS scaleA_val,
       Max(scaleB_val) AS scaleB_val,
       day from
       (select scaleA.val  scaleA_val,
        scaleB.val AS scaleB_val,
        To_char(From_dt1970(scaleA.time1970), 'DD') AS day
  FROM rsdu2elarh.el008_6305119 scaleA
  FULL OUTER JOIN rsdu2elarh.el008_6305126 scaleB
    ON scaleA.time1970 = scaleB.time1970
 WHERE scaleA.time1970 > To_dt1970(To_date('2019/11/01', 'yyyy/mm/dd'))
   AND scaleA.time1970 < To_dt1970(To_date('2019/12/01', 'yyyy/mm/dd'))
   )
 GROUP BY day
 ORDER BY day;

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

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