1

いくつかの列の最大値を持つ行を取得しようとしています。通常、これには Rank を使用し、rank = 1 を選択しますが、列の最大値だけが必要であることがわかっている場合、それは無意味に思えます。ここに私のSQLがあります:

SELECT
  name,
  value,
  MAX(version)
FROM
  my_table t
WHERE
  person_type = "STUDENT"
GROUP by NAME,VALUE
HAVING version = max(version)

これは、実行しようとすると、「グループ化エラーに関連して何か間違ったことをしました」、つまり「GROUP BY式ではありません」を返します。group by フィールドにバージョンを追加すると、この SQL が実行されますが、それぞれの最大バージョンだけでなく、明らかにすべての行が返されます。

したがって、私の質問は主に「なぜこれがうまくいかないのですか?」です。バージョンの最大値を選択しているので、それでグループ化する必要がある理由がわかりません。他の解決策(パーティションオーバー、ランク...)があることは知っていますが、特にこれが構文的に欠陥がある理由にもっと興味があります。

EDIT:このhaving句の使用についてより明確に。

テーブル t に次の 2 つの行があるとします。

NAME    VALUE    VERSION
JEREMY  C        1
JEREMY  A        2

このクエリから返されるものは次のとおりです。

JEREMY A 2

しかし、持っているものを削除すると、次のようになります。

JEREMY A 2
JEREMY C 2
4

4 に答える 4

2

通常、HAVING 句には、group by によって生成される列を含める必要があります。実際、HAVING 句は group by の WHERE と考えることができます。

つまり、次のクエリです。

select <whatever>
from t
group by <whatever>
having <some condition>

次と同等です。

select <whatever>
from (select <whatever>
      from t
      group by <whatever
     ) t
where <some condition>

このように考えると、max(version) は集計値であるため意味があることがわかります。ただし、「バージョン」は計算値でもグループごとの列でもないため、意味がありません。

あなたはこれを修正する方法を知っているようです。もう 1 つのコメントは、一部のデータベース (特に mysql) が構文を受け入れるということです。「HAVING version = max(version)」を「HAVING any(version) = max(version)」として扱います。

于 2012-06-20T19:27:38.653 に答える
1

versionHAVING 句で使用しようとしていますが、グループ化されていません。

HAVING名前、値、最大バージョンだけが必要な場合は、句はまったく必要ありません。

SELECT
  name,
  value,
  MAX(version)
FROM
  my_table t
WHERE
  person_type = "STUDENT"
GROUP by NAME,VALUE

HAVING 句は、集計後に「Where」句が必要な場合に使用します。

HAVING max(version) > 5

編集:

サンプル データに基づいて、VALUE でグループ化していますが、実際にやりたいことは、各 NAME の MAX(VERSION) を持つ VALUE を特定することです。

これを行うには、次のように WHERE EXISTS または自己結合を使用する必要があります。

select name, value, version from t 
where exists
(
  select 1 from
  (select name, max(version) version
     from t 
    group by name) s
  where s.name = t.name and s.version = t.version
)
于 2012-06-20T19:24:51.687 に答える
1

この SQL ステートメントは失敗します。これは、HAVING句がGROUP BY-- の後に実行されるためです。この SQL ステートメントは、句にリストされている集計または列に対してのみ操作できますGROUP BYNAMEandのみでグループ化した場合VALUEVERSION単独では意味がありません。その時点でのNAMEandのすべての組み合わせに対して多くの可能な値があるため、すべてのandに対して正確に 1 つの値を持つ他の集計と比較しても意味がありません。ペア。VALUEMAX(version)NAMEVALUE

于 2012-06-20T19:28:00.357 に答える
0

欲しいものを手に入れる別の方法:

select *
from (select name
        , value
        , version
        , max(version) over 
            (partition by name) as max_version
    from t)
where version = max_version;

実行例: SQL> create table t (name varchar2(30) 2 , value varchar2(1) 3 , version number not null 4 , constraint t_pk primary key (name, version));

Table created.

SQL> insert into t select 'JEREMY', 'C', 1 from dual
  2  union all select 'JEREMY', 'A', 2 from dual
  3  union all select 'SARAH', 'D', 2 from dual
  4  union all select 'SARAH', 'X', 1 from dual;

4 rows created.

SQL> commit;

Commit complete.

SQL> select name, value, version
  2  from (select name
  3          , value
  4          , version
  5          , max(version) over
  6              (partition by name) as max_version
  7      from t)
  8  where version = max_version;

NAME                           V    VERSION
------------------------------ - ----------
JEREMY                         A          2
SARAH                          D          2
于 2012-06-20T20:33:56.770 に答える