1

2 つのテーブル ( ManagementEmployee ) があります。

管理テーブルは、過去数年間に会社 X を管理してきたさまざまな管理チームを追跡します。各管理チームには ID (例: managementnr) が与えられ、各チームには CEO (つまり ceoname) がいます。

employee テーブルは、会社 X で働く従業員を追跡します (基本的には、従業員の名前と、どの管理チームが採用したかだけです)。

SQL コードは次のとおりです。


CREATE TABLE EMPLOYEE(
    EMPLOYEENAME   VARCHAR2(15) NOT NULL,
    HIRETEAM NUMBER(2), 
    PRIMARY KEY (EMPLOYEENAME)
    );

CREATE TABLE MANAGEMENT(
    MANAGEMENTNR NUMBER(2) NOT NULL,
    CEONAME VARCHAR2(20) NOT NULL,
    PRIMARY KEY (MANAGEMENTNR,CEONAME)
    );  

最も多くの従業員が雇用されている managementNR を取得する SQL クエリを作成しようとしています。私は使用してみました:

SELECT HIRETEAM,max(count(HIRETEAM)) 
 from EMPLOYEE 
group by HIRETEAM

しかし、私は取得し続けます:

  ORA-00937: not a single-group group function 

(私はオラクルを使用しています)

何時間も Google-fu を使用した後、ようやくこのエラーの意味がわかりましたが、このクエリを作成する他の方法はまだ考えられません。サブクエリ/結合を使用してみましたが、まだ何もありません。私は一般的にSQLに非常に慣れていません。誰かが助けることができれば、私は本当に感謝しています!

お時間をいただきありがとうございます =] --
エヴァン・レストレンジ

4

5 に答える 5

3

私はあなたがこれを探していると思います:

WITH counts_hireteam as (
   SELECT HIRETEAM
        , count(*) count_hireteam
     from EMPLOYEE 
   group by HIRETEAM
   order by count(*) desc
) 
select HIRETEAM  
  from counts_hireteam
 where rownum = 1;
于 2009-03-30T23:03:24.000 に答える
2

これを行う「正しい」方法は、実際には次のようなものです。

SELECT m.ceoname, COUNT(1), ROW_NUMBER() OVER (ORDER BY COUNT(1) DESC)
FROM management m
JOIN employee e ON m.managementnr = e.hireteam
GROUP BY m.ceoname

あなたは Top-N クエリのあいまいな領域に入り込んでいます。Top-Nについて Tom に質問するこの優れたコラムを紹介します。他の回答は単純なケースで機能しますが、トップ 3 の管理チーム (人数による) を返すなどのことをしたい場合や、一貫してそうする場合に問題が発生します。

一貫性が重要なポイントです。トムが指摘するように:

クエリの GROUP BY 句は、ORDER BY 句がなくても、出力データが GROUP BY 列で順番に並べ替えられることを保証しますか?

クエリに ORDER BY ステートメントがない限り、返される行は任意の順序であると見なすことはできません。ORDER BY がないと、データは、データベースが返すように感じる任意の順序で返される可能性があります。これは常に真実であり、常に真実です。

実際、Oracle Database 10g Release 2 では、GROUP BY がランダムな順序でデータを返すことが以前よりもはるかに頻繁に見られるようになります。

このサンプル データの使用:

INSERT INTO employee VALUES ('Bob',1);
INSERT INTO employee VALUES ('Sue',1);
INSERT INTO employee VALUES ('John',1);
INSERT INTO employee VALUES ('James',2);
INSERT INTO employee VALUES ('Mary',2);
INSERT INTO employee VALUES ('Ron', 2);
INSERT INTO employee VALUES ('Jane',3);
INSERT INTO employee VALUES ('Luke',4);
INSERT INTO employee VALUES ('Rob',4);
INSERT INTO employee VALUES ('Tim', 5);

INSERT INTO management VALUES (1, 'Kate');
INSERT INTO management VALUES (2, 'Larry');
INSERT INTO management VALUES (3, 'Jake');
INSERT INTO management VALUES (4, 'Sarah');
INSERT INTO management VALUES (5, 'Tom');
于 2009-03-30T23:04:04.733 に答える
2

このクエリから最初の行を取得します。

select hireteam,count(*) from EMPLOYEE group by hireteam order by count(*) desc
于 2009-03-30T22:46:23.807 に答える
0

採用数が同数の場合でも、結果を 1 つのレコードに限定したい場合は、次のようにします。

select * from (
    select hireteam, count(hireteam) count
    from employee
    group by hireteam
    order by count(hireteam) desc, hireteam asc )
where rownum = 1

採用数が最も多い (同点を含む) すべての hitteam 値を取得するには、次のようにします。

select * from (
    select hireteam,
           count(hireteam) count,
           rank() over (order by count(hireteam) desc) rank
    from   employee
    group by hireteam)
where rank = 1;
于 2009-03-30T23:22:19.043 に答える
0

このようにして、雇用された従業員の数を持つすべてのチームを取得します。

select
    Management.ManagementNr,
    Management.CeoName,
    count(Employee.EmployeeName)   
from 
    Employee 
inner join 
    Management on Employee.HireTeam = Management.ManagementNr   
group by 
    Management.ManagementNr   
order by 
    count(Employee.EmployeeName) desc

追加の has 句を追加し、結合を放棄すると (私が認識したように CEO 名は必要ないため)、次のように目的の結果が得られます。

select Employee.HireTeam   
from Employee   
group by Employee.HireTeam   
having count(EmployeeName) = select max(GroupSize)
   from select count(EmployeeName) as GroupSize
      from Employee group by Employee.HireTeam

複数の経営陣が同じ数の従業員を雇用した場合、実際には複数の行が返されることがあります。そして、それは醜いです...しかし、その場しのぎの私は、単一のクエリでそれを行うより良い方法を知りません。

于 2009-03-30T22:46:31.063 に答える