'group by' работает на MySQL, но не на Oracle - PullRequest
4 голосов
/ 07 июля 2010

У меня есть запрос, который работает на 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 был максимальным (например, 2 для http_session_id == 123456789), но это несущественно.

Я на грани разбиения этого на несколько отдельных SQL-операторов (один ")выберите отличный http_session_id ", а другой, чтобы перебрать все это, и выберите максимум (unique_row_id). Любые указатели будут с благодарностью приняты - я хотел бы избежать этого!

Rgds, Кевин.

Ответы [ 5 ]

10 голосов
/ 07 июля 2010

Причина, по которой вы сталкиваетесь с ошибкой ORA, заключается в том, что MySQL поддерживает нестандартные предложения GROUP BY, называя это «функцией».Здесь задокументировано .

Стандартное предложение SQL GROUP BY должно включать ALL столбцы, указанные в предложении SELECT, которые не объединяются в агрегатфункции (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
2 голосов
/ 07 июля 2010

Будет ли это работать:

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

Кстати ; что мой sql возвращает в вашем наборе результатов для columsn, которые включены в набор результатов, но не в предложение group by? (имя_страницы, page_hit_timestamp)

0 голосов
/ 07 июля 2010

Другой вариант в 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
0 голосов
/ 07 июля 2010

В стандартном 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
0 голосов
/ 07 июля 2010

Я думаю, что GROUP BY требует, чтобы переменная использовалась в предложении WHERE или функции агрегирования в стандарте SQL?

Попробуйте использовать SELECT MAX(unique_row_id) GROUP BY http_session_id.

...