[英]'group by' works on MySQL, but not Oracle
我有一个适用于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语句(一个“select distinct http_session_id”,另一个迭代所有这些并选择max(unique_row_id)。任何指针都会被感激地收到 - 我很想避免这个!
Rgds,凯文。
您遇到ORA错误的原因是因为MySQL支持非标准GROUP BY子句,称其为“功能”。 它在这里记录 。
标准SQL GROUP BY子句必须包含SELECT子句中指定的所有列,这些列不包含在GROUP BY子句中指定的聚合函数(LIKE COUNT,MAX / MIN等)中。
如果你想为每个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
这会工作:
select max(unique_row_id), http_session_id
from page_hits
group by http_session_id
顺便说一下 ; 我的sql在结果集中返回的结果集中返回的columsn是什么,而不是group by子句? (page_name,page_hit_timestamp)
我认为GROUP BY需要在SQL标准的WHERE子句或聚合函数中使用变量吗?
尝试使用SELECT MAX(unique_row_id) GROUP BY http_session_id
。
在标准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
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_id
, page_name
和page_hit_timestamp
从具有最大的行unique_row_id
为http_session_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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.