0

テーブルから 2 つの値を選択しようとしています。従業員 emp_name、emp_location によってグループ化され、emp_location によってグループ化されています。関数によってグループ化されている列は select 句に含まれている必要があることを認識していますが、取得する他の方法があるかどうかを知りたいです。単一のクエリでこれらの値を取得します。

私の意図は、年齢に基づいて、場所ごとに 1 人の従業員のみを選択することです。サンプルクエリ

select emp_name,emp_location 
from Employee 
where emp_age=25 
group by emp_location

この点で助けてください。

この質問に答えてくれたすべての人に感謝します。これらのウィンドウ機能は非常に便利なので、学習しようと思います。

4

3 に答える 3

2

これが Oracle ではなく MySQL で機能する理由は、Oracle では、他のほとんどのデータベースと同様に、group by句でフィールド (または式) を指定する必要があるか、または次の値を組み合わせた集計である必要があるためです。グループ内のすべての値を 1 つの値にします。たとえば、これはうまくいきます:

select max(emp_name),emp_location 
from Employee 
where emp_age=25 
group by emp_location

ただし、それは最善の解決策ではない可能性があります。名前だけが必要な場合は機能しますが、従業員に複数のフィールドが必要な場合は問題が発生します。その場合max、うまくいきません。以下のクエリでは、姓と一致しない名を取得する場合があります。

select max(emp_firstname), max(emp_lastname), emp_location 
from Employee 
where emp_age=25 
group by emp_location 

これを解決するには、ウィンドウ関数(分析関数)を使用します。これらを使用すると、レコード数をすぐに減らすことなく、各レコードの値を生成できます。たとえば、ウィンドウ化されたmax関数を使用して、 という名前の人物の最大年齢を選択し、Johnその年齢でなくても、結果のすべてのジョンの横にその値を表示できます。

やなどrankの一部の関数を使用して、各従業員の数値を生成し、それを使用してフィルター処理できます。以下の例では、このようなカウンターをロケーションごとに作成し (partition by)、並べ替えました (この場合は name と id)。他のフィールドも指定できます。たとえば、場所ごとに年齢ごとに 1 つの名前が必要な場合は、年齢と場所の両方を で指定します。各場所の最も古い従業員が必要な場合は、代わりにandを削除できます。dense_rankrow_numberpartition bywhere emp_age=25order by emp_age desc

select
  *
from
  (select 
    emp_name, emp_location,
    dense_rank() over (partition by emp_location order by emp_name, emp_id) as emp_rank
  from Employee 
  where emp_age=25)
where
  emp_rank = 1
于 2015-01-01T11:52:16.487 に答える
2

ORA-00979 Group By 関数ではないエラー

句で指定された集計関数列のみがGROUP BY句で許可されSELECTます。

その点で、Oracle は SQL 標準に厳密に従っています。しかし、あなたのコメントで気づいたように、他のいくつかの RDBMS は、その点に関して Oracle ほど厳密ではありません。たとえば、MySQL のドキュメントを引用するには(強調は私のものです):

MySQL は GROUP BY の使用を拡張して、選択リストが GROUP BY 句で指定されていない非集計列を参照できるようにします。[...]

ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じである場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。

したがって、推奨される使用例では、余分な列をGROUP BY句に追加しても同じ結果になります。


select emp_name,emp_location 
--     ^^^^^^^^
--   this is *not* part of the ̀`GROUP BY` clause
from Employee 
where emp_state=25 
group by emp_location

多分あなたは探しています:

...
group by emp_location, emp_name
于 2015-01-01T11:21:30.700 に答える
0
select emp_name,emp_location
from Employee
where emp_age=25
group by emp_name,emp_location

また

select max(emp_name) emp_name,emp_location
from Employee
where emp_age=25
group by emp_location 
于 2015-01-01T11:44:05.897 に答える