Oracle GROUP BY 给出错误 ORA-00979:不是 GROUP BY 表达式

发布于 2024-12-12 00:55:42 字数 1111 浏览 0 评论 0原文

假设我们有两个表

table1
    ----------------------
    |ID         | Date   |
    ----------------------
    |1          |20110101|
    |1          |20110102|
    |1          |20110103|
    |2          |20110102|
    |2          |20110103|
    |2          |20110104|
    ----------------------

table2
    ----------------------
    |ID2        |val     |
    ----------------------
    |1          |152     |
    |2          |155     |
    ----------------------

使用这个查询

SELECT * FROM table1, table2
WHERE table1.ID = table2.ID2
GROUP BY table1.ID 
ORDER BY DATE DESC

Mysql应该返回这个

-------------------------------------------
|ID         |date    |ID2        |val     |
-------------------------------------------
|1          |20110103|1          |152     |
|2          |20110104|2          |155     |
-------------------------------------------

在Oracle中我得到这个错误: ORA-00979:不是 GROUP BY 表达式

编辑: Date 列上的 MAX 函数不起作用,因为该列是 varchar(200) 数据库/表结构不是我的,我无法更改它。

let's assume we have two tables

table1
    ----------------------
    |ID         | Date   |
    ----------------------
    |1          |20110101|
    |1          |20110102|
    |1          |20110103|
    |2          |20110102|
    |2          |20110103|
    |2          |20110104|
    ----------------------

table2
    ----------------------
    |ID2        |val     |
    ----------------------
    |1          |152     |
    |2          |155     |
    ----------------------

Using this query

SELECT * FROM table1, table2
WHERE table1.ID = table2.ID2
GROUP BY table1.ID 
ORDER BY DATE DESC

Mysql should return this

-------------------------------------------
|ID         |date    |ID2        |val     |
-------------------------------------------
|1          |20110103|1          |152     |
|2          |20110104|2          |155     |
-------------------------------------------

In Oracle I get this error:
ORA-00979: not a GROUP BY expression

EDIT:
The MAX function on the column Date does not work because this column is varchar(200)
The database/tables structure is not mine and I cannot alter it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

维持三分热 2024-12-19 00:55:42

您需要执行两件事之一...

  • GROUP BY 并使用聚合函数将多条记录合并为一条
  • 使用一些查找来从组中识别您想要的一条记录

在您的情况下,您不只是想要来自 table1 的 MAX(),因为可能较高的 id 具有较低的日期。在这种情况下,我倾向于使用查找系统...

WITH
  ordered_table1 AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY date_field DESC) AS sequence_number,
    *
  FROM
    table1
)
SELECT
  *
FROM
  ordered_table1
INNER JOIN
  table2
    ON table2.id = ordered_table1.id
WHERE
  ordered_table1.sequence_id = 1

注意:这假设您的日期格式为字母数字排序将产生正确的日期顺序。如果情况并非如此(并且 dm-yyyy无法正确排序),您需要替换 date_field使用 TO_DATE(date_field) 确保顺序正确。

注意:使用TO_DATE(date_field)也可能会解决您的 MAX() 问题。

注意:如果您想将日期存储为字符串,但为了顺序友好,请使用yyyy-mm-dd

You need to do one of two things...

  • GROUP BY and use aggregate functions to consolidate multiple records down to one
  • Use some lookup to identify the one record you want from the group

In your case, you don't just want a MAX() from table1, as it may be possible that a higher id has a lower date. In that case, I'd be inclined to use a lookup system...

WITH
  ordered_table1 AS
(
  SELECT
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY date_field DESC) AS sequence_number,
    *
  FROM
    table1
)
SELECT
  *
FROM
  ordered_table1
INNER JOIN
  table2
    ON table2.id = ordered_table1.id
WHERE
  ordered_table1.sequence_id = 1

NOTE: This assumes your date is formatted such that alphanumeric ordering WILL yield the correct date order. If that is NOT the case (and d-m-yyyy will not order correctly), you need to replace date_field with TO_DATE(date_field) to ensure the correct order.

NOTE: Use of TO_DATE(date_field) will also probably fix your MAX() problems.

NOTE: If you want to store dates as strings, but them to be order friendly, use yyyy-mm-dd

如何视而不见 2024-12-19 00:55:42

在带有 group by 的 SQL 语句的 select 和 order by 子句中,只能使用 group by 中使用的列/表达式或其他列的聚合函数(min、max、avg ..)。

我知道 Oracle 是这样,但令我感到有点惊讶的是 MySQL 中的情况有所不同

In the select and order by clause of a SQL Statement with group by you can only use the columns/expression used in the group by or aggregate functions (min, max, avg ..) of other columns.

I know this for oracle and I am a little surprised that this is different in MySQL

瘫痪情歌 2024-12-19 00:55:42

按以下方法尝试一下:

   SELECT *
     FROM table1
LEFT JOIN table2 
       ON table1.ID = table2.ID
 ORDER BY DATE DESC
 GROUP BY table1.ID

Try it in following way:

   SELECT *
     FROM table1
LEFT JOIN table2 
       ON table1.ID = table2.ID
 ORDER BY DATE DESC
 GROUP BY table1.ID
海拔太高太耀眼 2024-12-19 00:55:42

一般来说,将 select * fromgroup by 结合使用是一个坏主意。 select 子句中的表达式需要是标量,即要么是组的聚合函数,要么与分组无关,要么是在 group by 子句本身中。 Select * 几乎保证不会出现这种情况。你可能想要这样的东西:

select t1.id, max(t1.date), t2.id, max(t2.val)
  from table1 t1
  join table2 t2 on t1.id=t2.id
  group by t1.id
  order by  max(t1.date) desc

In general, saying select * from in combination with group by is a bad idea. The expressions in the select clause need to be scalar, that is, either aggregate functions of the group, or unrelated to the grouping, or in the group by clause themselves. Select * pretty much guarantees that that will not be the case. You probably want something like this instead:

select t1.id, max(t1.date), t2.id, max(t2.val)
  from table1 t1
  join table2 t2 on t1.id=t2.id
  group by t1.id
  order by  max(t1.date) desc
情独悲 2024-12-19 00:55:42

Oracle 中的 Group by 意味着您正在尝试对其中一列运行聚合函数(求和、计数等)。看来您只是想先按 ID 订购,然后再按日期订购。我会做这样的事情:

SELECT * 
FROM   table1
       JOIN table2 ON (table1.ID = table2.ID2)
ORDER BY ID,
         DATE DESC

如果这不是您想要的,那么答案是您需要 select 子句中不属于聚合函数的每一列都位于 group 子句中。

编辑

响应评论:

最好首先将表1作为子查询进行过滤,然后连接到表2:

SELECT *
FROM   (SELECT DISTINCT ID,MAX(TO_DATE(DATE,'mm-dd-yyyy')) FROM Table1 GROUP BY ID) T1
       JOIN Table2 ON (T1.ID = Table2.ID2)
ORDER BY date DESC

Group by in oracle implies that you are trying to run an aggregate function (sum, count, etc.) on one of the columns. It appears that you are just looking to order by ID first and then the date. I would do something like this:

SELECT * 
FROM   table1
       JOIN table2 ON (table1.ID = table2.ID2)
ORDER BY ID,
         DATE DESC

If that is not what you are intending, then the answer is that you need each column in the select clause that is not part of an aggregate function to be in the group clause.

EDIT

In response to the comment:

It's probably best to filter table 1 down first as a subquery and then join to table2:

SELECT *
FROM   (SELECT DISTINCT ID,MAX(TO_DATE(DATE,'mm-dd-yyyy')) FROM Table1 GROUP BY ID) T1
       JOIN Table2 ON (T1.ID = Table2.ID2)
ORDER BY date DESC
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文