4

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 ごとに 1 つ)。

Oracle では、「ORA-00979: GROUP BY 式ではありません」というエラーが表示されます。私もdistinctで遊んでみましたが、うまくいきません。

明確にするために、一意の http_session_id ごとに 1 つの行を含む ResultSet が必要です。unique_row_id は最大値 (たとえば、http_session_id==123456789 の場合は 2) であることが望ましいですが、これは重要ではありません。

私はこれを複数の個別のSQLステートメントに分割する寸前です(1つは「個別のhttp_session_idを選択」、もう1つはこれらすべてを繰り返し処理してmax(unique_row_id)を選択します。ポインターは喜んで受け取ります-避けたいですこれ!

Rgds、ケビン。

4

5 に答える 5

10

ORA エラーが発生する理由は、MySQL が非標準の GROUP BY 句をサポートし、それを「機能」と呼んでいるためです。ここに文書化されています

標準 SQL GROUP BY 句には、GROUP BY 句で指定される集計関数 (LIKE COUNT、MAX/MIN など) でラップされていない、SELECT 句で指定されたすべての列を含める必要があります。

http_session_id 値ごとに 1 つの一意の行が必要な場合は、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
于 2010-07-06T22:17:35.520 に答える
2

これはうまくいきますか:

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

ちなみに;結果セットに含まれているが group by 句には含まれていない列の場合、SQL は結果セットに何を返しますか? (page_name, page_hit_timestamp)

于 2010-07-06T22:17:31.740 に答える
0

GROUP BY には、SQL 標準の WHERE 句または集計関数で変数が使用されている必要があると思いますか?

を使ってみてくださいSELECT MAX(unique_row_id) GROUP BY http_session_id

于 2010-07-06T22:14:35.830 に答える
0

標準 SQL では、GROUP BY 句がある場合、その一部ではないすべての列を集計する必要があります。MySQL では、このルールは設計により緩和されました。

たとえば、これは MySQL では許可されていますが、標準 SQL では許可されていません。

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

注意点が 1 つあります。MySQL は、ユーザーが何をしているかを理解していることを前提としています。同じ顧客が複数の国でレコードを持っている場合、クエリはテーブルの最初の国を取得し、他の国はすべて無視します。さらに、行の順序は定義されておらず、ORDER BY がないため、クエリを実行するたびに異なる結果が得られる可能性があります。

標準 SQL では、次の 2 つの選択肢があります。

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
于 2010-07-06T22:42:38.300 に答える
0

必要に応じて、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_timestampunique_row_idhttp_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
于 2010-07-07T01:16:37.400 に答える