“分组依据”适用于 MySQL,但不适用于 Oracle

发布于 2024-09-08 18:07:24 字数 1313 浏览 3 评论 0原文

我有一个适用于 MySQL 但不适用于 Oracle 的查询,我正在尝试进行转换。这是我的表:

unique_row_id  http_session_id  page_name   page_hit_timestamp
----------------------------------------------------------------
0              123456789        index.html  2010-01-20 15:00:00
1              123456789        info.html   2010-01-20 15:00:05
2              123456789        faq.html    2010-01-20 15:00:15
3              987654321        index.html  2010-01-20 16:00:00
4              987654321        faq.html    2010-01-20 16:00:05
5              987654321        info.html   2010-01-20 16:00:15
6              111111111        index.html  2010-01-20 16:01:00
7              111111111        faq.html    2010-01-20 16:01:05
8              111111111        info.html   2010-01-20 16:01:15

SQL 在

select http_session_id, unique_row_id, page_name, page_hit_timestamp 
from page_hits 
group by http_session_id;

MySQL 上,这将返回 3 行(每个唯一的 http_session_id 一行)。

在 Oracle 上,我收到“ORA-00979:不是 GROUP BY 表达式”错误。我也尝试过使用不同的方法,但我无法让它发挥作用。

需要明确的是 - 我想要一个 ResultSet,其中每个唯一的 http_session_id 包含一行。最好是 unique_row_id 是最大的(例如,http_session_id==123456789 为 2),但这并不重要。

我即将将其分解为多个单独的sql语句(一个“选择不同的http_session_id”,另一个迭代所有这些并选择max(unique_row_id)。任何指针将不胜感激地收到 - 我很想避免这个,

凯文。

I have a query that works on MySQL but doesn't work on Oracle, and I'm trying to convert. This is my table:

unique_row_id  http_session_id  page_name   page_hit_timestamp
----------------------------------------------------------------
0              123456789        index.html  2010-01-20 15:00:00
1              123456789        info.html   2010-01-20 15:00:05
2              123456789        faq.html    2010-01-20 15:00:15
3              987654321        index.html  2010-01-20 16:00:00
4              987654321        faq.html    2010-01-20 16:00:05
5              987654321        info.html   2010-01-20 16:00:15
6              111111111        index.html  2010-01-20 16:01:00
7              111111111        faq.html    2010-01-20 16:01:05
8              111111111        info.html   2010-01-20 16:01:15

The SQL is

select http_session_id, unique_row_id, page_name, page_hit_timestamp 
from page_hits 
group by http_session_id;

On MySQL, this will return 3 rows (one for each unique http_session_id).

On Oracle, I get a "ORA-00979: not a GROUP BY expression" error. I've tried playing around with distinct too, but I can't get it to work.

Just to be clear - I would like a ResultSet that contains one row per unique http_session_id. It is preferable that the unique_row_id would be the max one (e.g. 2 for http_session_id==123456789), but this is not significant.

I'm on the verge of breaking this into multiple separate sql statements (one "select distinct http_session_id", and the other to iterate through all these and select the max(unique_row_id). Any pointers would be gratefully received - I would love to avoid this!

Rgds, Kevin.

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

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

发布评论

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

评论(5

留蓝 2024-09-15 18:07:24

您遇到ORA错误的原因是因为MySQL支持非标准GROUP BY子句,称其为“功能”。 记录在此处

标准 SQL GROUP BY 子句必须包含 SELECT 子句中指定的 ALL 列,这些列未包装在聚合函数(LIKE COUNT、MAX/MIN 等)中,以便在 GROUP BY 子句中指定。

如果您想要每个 http_session_id 值有一个唯一的行 - 请查看使用 ROW_NUMBER:

SELECT x.*
  FROM (select http_session_id, unique_row_id, page_name, page_hit_timestamp,
               ROW_NUMBER() OVER (PARTITION BY http_session_id 
                                      ORDER BY http_session_id) AS rank
          FROM page_hits) x
 WHERE x.rank = 1

The reason you encounter the ORA error is because MySQL supports non-standard GROUP BY clauses, calling it a "feature". It's documented here.

The standard SQL GROUP BY clause must include ALL columns specified in the SELECT clause, that are not wrapped in aggregate functions (LIKE COUNT, MAX/MIN, etc), to be specified in the GROUP BY clause.

If you want one, unique row per http_session_id value - look at using ROW_NUMBER:

SELECT x.*
  FROM (select http_session_id, unique_row_id, page_name, page_hit_timestamp,
               ROW_NUMBER() OVER (PARTITION BY http_session_id 
                                      ORDER BY http_session_id) AS rank
          FROM page_hits) x
 WHERE x.rank = 1
她如夕阳 2024-09-15 18:07:24

这行得通吗:

select max(unique_row_id), http_session_id
from page_hits
group by http_session_id

顺便说一下;对于包含在结果集中但不包含在 group by 子句中的列,我的 sql 在结果集中返回什么? (页面名称、页面点击时间戳)

Would this work:

select max(unique_row_id), http_session_id
from page_hits
group by http_session_id

Incidentally; what does my sql return in your resultset for columsn that are included in the resultset but not in the group by clause? (page_name, page_hit_timestamp)

守护在此方 2024-09-15 18:07:24

我认为 GROUP BY 需要在 SQL 标准中的 WHERE 子句或聚合函数中使用变量?

尝试使用SELECT MAX(unique_row_id) GROUP BY http_session_id

I think that a GROUP BY requires a variable to have been used in a WHERE clause or aggregation function in the SQL standard?

Try using SELECT MAX(unique_row_id) GROUP BY http_session_id.

七度光 2024-09-15 18:07:24

在标准 SQL 中,如果有 GROUP BY 子句,则不属于该子句的所有列都必须聚合。在 MySQL 中,这条规则在设计上被放宽了。

例如,这在 MySQL 中是允许的,但在标准 SQL 中不允许:

SELECT customer_id, country, SUM(amount) FROM records GROUP BY customer_id

有一个警告:MySQL 假设您知道自己在做什么。如果同一客户在多个国家/地区有记录,则查询将仅获取表中的第一个国家/地区,而忽略所有其他国家/地区。此外,由于行的顺序未定义,并且没有 ORDER BY,因此每次运行查询时可能会得到不同的结果。

在标准 SQL 中,您有两种选择:

SELECT customer_id, country, SUM(amount) FROM records GROUP BY customer_id, country

SELECT customer_id, MIN(country), SUM(amount) FROM records GROUP BY customer_id

In standard SQL, if you have a GROUP BY clause, all columns that are not part of it have to be in aggregates. In MySQL, this rule was relaxed by design.

For instance, this is allowed in MySQL but not in standard SQL:

SELECT customer_id, country, SUM(amount) FROM records GROUP BY customer_id

There's one caveat: MySQL assumes you know what you're doing. If the same customer has records in multiple countries, the query will simply grab the first country in the table, disregarding all others. Furthermore, since the order of rows is undefined, and there is no ORDER BY, you might get different results each time you run the query.

In Standard SQL, you have two choices:

SELECT customer_id, country, SUM(amount) FROM records GROUP BY customer_id, country

or

SELECT customer_id, MIN(country), SUM(amount) FROM records GROUP BY customer_id
临走之时 2024-09-15 18:07:24

Oracle 中的另一个选项(如果需要):

select DISTINCT
       FIRST_VALUE(unique_row_id)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) unique_row_id,
       http_session_id,
       FIRST_VALUE(page_name)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) page_name,
       FIRST_VALUE(page_hit_timestamp)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) page_hit_timestamp
from page_hits;

这将获得一组不同的 http_session_id,并且对于每个,返回 unique_row_idpage_namepage_hit_timestamp 来自该 http_session_id 具有最大 unique_row_id 的行,例如:

unique_row_id  http_session_id  page_name   page_hit_timestamp
----------------------------------------------------------------
2              123456789        faq.html    2010-01-20 15:00:15
5              987654321        info.html   2010-01-20 16:00:15
8              111111111        info.html   2010-01-20 16:01:15

Another option in Oracle, if you want:

select DISTINCT
       FIRST_VALUE(unique_row_id)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) unique_row_id,
       http_session_id,
       FIRST_VALUE(page_name)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) page_name,
       FIRST_VALUE(page_hit_timestamp)
       OVER (PARTITION BY http_session_id
             ORDER BY unique_row_id DESC) page_hit_timestamp
from page_hits;

This will get a distinct set of http_session_id's, and for each, returns the unique_row_id, page_name and page_hit_timestamp from the row with the greatest unique_row_id for that http_session_id, e.g.:

unique_row_id  http_session_id  page_name   page_hit_timestamp
----------------------------------------------------------------
2              123456789        faq.html    2010-01-20 15:00:15
5              987654321        info.html   2010-01-20 16:00:15
8              111111111        info.html   2010-01-20 16:01:15
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文