2017-08-02 23 views
1

私はSQLへのイントロを行っていますが、現在私はこの練習をしていますが、私は立ち往生しています。部門ごとの平均給与

演習:

部署名、管理者ID、その部門のマネージャ名(従業員姓)、および各部門の平均給与のリストを作成します。

以下は、私が使っているテーブルだけです。これは私が今持っているものである

CREATE TABLE "EMPLOYEES" 
("EMPLOYEE_ID" NUMBER(6,0), 
"FIRST_NAME" VARCHAR2(20), 
"LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE, 
"EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE, 
"PHONE_NUMBER" VARCHAR2(20), 
"HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE, 
"JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE, 
"SALARY" NUMBER(8,2), 
"COMMISSION_PCT" NUMBER(2,2), 
"MANAGER_ID" NUMBER(6,0), 
"DEPARTMENT_ID" NUMBER(4,0), 
"BONUS" VARCHAR2(5), 
CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE, 
CONSTRAINT "EMP_ID_PK" PRIMARY KEY ("EMPLOYEE_ID") 
USING INDEX ENABLE, 
CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL") 
USING INDEX ENABLE 
); 

CREATE TABLE "DEPARTMENTS" 
("DEPARTMENT_ID" NUMBER(4,0), 
"DEPARTMENT_NAME" VARCHAR2(30) CONSTRAINT "DEPT_NAME_NN" NOT NULL ENABLE, 
"MANAGER_ID" NUMBER(6,0), 
"LOCATION_ID" NUMBER(4,0), 
CONSTRAINT "DEPT_ID_PK" PRIMARY KEY ("DEPARTMENT_ID") 
USING INDEX ENABLE 
); 

select d.department_name, d.manager_id,e.last_name as "manager_name" , 
avg(salary) 
from departments d join employees e ON (e.employee_id=d.manager_id) 
group by d.department_name,e.last_name, d.manager_id; 

私はそれが平均を除くために尋ねたすべてのフィールドを生成することができた、私は別のクエリ

を行うことで答えを手に入れました
select department_name, round(avg(salary)) from employees e join 
departments d ON (e.department_id=d.department_id) 
group by department_name; 

私は平均給与を与える選択声明が働くようにする方法を私の人生のために把握することはできません、私はHAVING句を試してみました。 en。うまくいけば誰かが私に何が欠けているか説明することができます。返事を感謝します!

+0

あなたはどのようなデータベース・サーバを使用していますか? –

+0

Oracle SQLデータベース – Rafa579

答えて

1

従業員はマネージャと非マネージャの両方を引用し、部門にはマネージャがあるため、同じSQLでTWICE部門に従業員テーブルを追加する必要があります。 Youreのは、これらの両方を探している同じSQLに参加する:

departments inner join employees mgrs on departments.manager_id = mgrs.employee_id 

はこの部門

departments inner join employees emps on emps.department_id = departments.department_id 
を従業員に関連付けます参加:


この部門でマネージャーの詳細を関連付けます参加します


だから、あなたの究極のSQLは、それのどこかで次のようになります:

FROM 
departments 
INNER JOIN employees mgrs ON .... 
INNER JOIN employees emps ON .... 
WHERE 

混乱?あなたに関連する別の例を考えてみましょう。あなたはあなたが住んでいる住所とあなたが働いている住所を持っています。データベースの場合は、おそらくテーブルpersonsaddressesがあります。自宅/職場の住所は単なる住所なので、personshome_addresseswork_addressesはありません。 Personsテーブルにはhome_address_idwork_address_idがありますが、アドレスの2つの異なるアドレス行を指している別のIDが各列にあります。つまり、住所を一度に登録して仕事と自宅住所の両方を取得する方法はありません。論理的にはうまくいかない:アドレス欄のセットが1つだけの場合、そのデータはあなたの仕事や家に表示されますか? 1つのセルに2つの値を重ねて表示することはできません。セルを追加する必要があります。私たちは既存の細胞ブロックの右側にもっと細胞を加えることによって...もう一度結合する!選択リストに列を含める場合:

person.Name, 
homeaddress.Street, 
workaddress.Street 

次にアドレスを2回入力する必要があります。

Person table 
------------ 
Name  Home_Address_Id Work_Address_Id 
JohnSmith 1    2 

Address table 
------------- 
ID Building Street 
1 261   Great Hope Street 
2 Office2000 Commercial Way 

うまくいけば、それは仕事と家庭のためのあなたの住所が異なっていることを確認するためにも明らかだん(OK、あなたは街で働く、と国に住んでいる何のホームワーキング許可;?))、「あなたができるので、 tは言う:

person p INNER JOIN address a ON p.home_address_id = a.id AND p.work_address_id = a.id 

データベースは、2つのテーブルを結合することは、あなたのON条件を処理する前に、それは(概念的には)すべての行にすべての行を結合し、それが

Persons-Joined-To-Addresses 
--------------------------- 
Name  Home_Address_Id Work_Address_Id ID Building Street 
JohnSmith 1    2    1 261   Great Hope Street 
JohnSmith 1    2    2 Office2000 Commercial Way 

することはできSをフィルタリングするときので、

Does 1=1 and 2=1? No. Do not include the 'JohnSmith 1    2    1 261   Great Hope Street' row 
Does 1=2 AND 2=2? No. Do not include the 'JohnSmith 1    2    2 Office2000 Commercial Way' row 

あなたががTWICEのアドレスに参加した場合、うまく:データベースは満足しているいずれかのテストを、それが生成された行をスキャンするので、両方の条件を満たした任意の行はすべての条件ON、存在しないことをEEこれは異なるものです:

Persons-Joined-To-Addresses-Joined-To-Addresses-Again 
----------------------------------------------------- 
Name  Home_Address_Id Work_Address_Id IH BuildingH StreetH   IW BuildingW StreetW 
JohnSmith 1    2    1 261   Great Hope Street 1 261   Great Hope Street 
JohnSmith 1    2    1 261   Great Hope Street 2 Office2000 Commercial Way 
JohnSmith 1    2    2 Office2000 Commercial Way 1 261   Great Hope Street 
JohnSmith 1    2    2 Office2000 Commercial Way 2 Office2000 Commercial Way 

これらの4つの行のうち、ジョインの条件を満たすものは1つだけです。ここではデータベースが行うテストのリストです:

Does 1=1 and 2=1? No. Don't include the 'JohnSmith/Great Hope Street/Great Hope Street' row 
Does 1=1 and 2=2? YES. Include the 'JohnSmith/Great Hope Street/Commercial Way' row 
Does 1=2 AND 2=1? No. Do not include the 'JohnSmith/Commercial Way/Great Hope Street' row 
Does 1=2 AND 2=2? No. Do not include the 'JohnSmith/Commercial Way/Commercial Way' row 

は、2つの条件が以前と同じですが、私はIHとIWとしてID列の名前を変更しました。条件はhome_address_id = IH and work_address_id = IWです。あなたが 'a = b AND x = yですか?'という概念を理解することは非常に重要です。上記の行は、「自宅」や「仕事」の意味を付け加えて、住所のIDを別の方法で扱っていることに感謝しています。言っていた:

は、人を行います。 _address_id = id_from_addresses_ aliased_as_home人。 仕事 _address_id = id_from_addresses_ aliased_as_work


使用すると、1つのSQLにこれを取得した後、従業員の給与を合計しても機能します。あなたの従業員テーブルを別々にエイリアスにする。私は鉱山のマネージャーと役人と呼ばれているので、データが「マネージャーレベル」か「従業員レベル」かを知っています

これは明らかに宿題ですので、 、投稿したコメント:)

+0

あなたの応答を感謝してくださいbtw! :) – Rafa579

+0

私は最初に部署から持っていましたが、従業員e ON(e.employee_id = d.manager_id)AND(e.department_id = d.department_id)に参加し、同じ回答を与えました。 – Rafa579

+0

しかし、それは両方の条件を満たす行で一度にemployeesテーブルを結合するだけです...私は "SQLはテーブルを2回結合する必要があります"と言いますと、文字通り 'department inner join employees mgrあなたがのためにはCtrl + Fをした場合、従業員は 'つまり... ON EMPに...インナーに参加することがMANAGER_NAME」として –

0

はあなたが後にしている何本か?

select d.department_name, d.manager_id,e.last_name as "manager_name", avg(salary) 
from departments d join employees e ON (e.employee_id=d.manager_id) 
group by d.department_name,d.manager_id, e.last_name ; 
+1

これは何が違うのか、それがなぜその質問に答えるかもしれないと思うのかを説明する方が良いでしょう。 –

+0

それは、私が持っていたものと同じ答えで出てきました。部門ごとの平均は示されません。 – Rafa579

+0

サンプル回答を投稿できますか? –

関連する問題