CREATE TABLE DEPARTMENTS
( DEPARTMENT_ID NUMERIC(4,0),
"DEPARTMENT_NAME" VARCHAR(30 ) CONSTRAINT DEPT_NAME_NN NOT NULL ,
"MANAGER_ID" NUMERIC(6,0),
"LOCATION_ID" NUMERIC(4,0),
);
CREATE TABLE EMPLOYEES
( EMPLOYEE_ID NUMERIC(6,0),
FIRST_NAME VARCHAR(20 ),
LAST_NAME VARCHAR(25 ) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ,
EMAIL VARCHAR(25 ) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ,
PHONE_NUMBER VARCHAR(20 ),
HIRE_DATE DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ,
JOB_ID VARCHAR(10 ) CONSTRAINT "EMP_JOB_NN" NOT NULL ,
SALARY NUMERIC(8,2),
COMMISSION_PCT NUMERIC(2,2),
MANAGER_ID NUMERIC(6,0),
DEPARTMENT_ID NUMERIC(4,0),
);
I need to list the name of the department, average salary and number of employees working in that department who got commission.
SELECT DEPARTMENT_NAME, AVG(SALARY), COUNT(COMMISSION_PCT)
FROM DEPARTMENTS JOIN EMPLOYEES USING (DEPARTMENT_ID);
GROUP BY DEPARTMENT_NAME
This is what I've got so far, but it gives me an error:
"DEPARTMENT_ID" is not a recognized table hints option. If it is intended as a parameter to a table-valued function or to the CHANGETABLE function, ensure that your database compatibility mode is set to 90.
I don't know which DBMS did you use.
I think that will be work,when you use INNER JOIN instead of USING
SELECT DEPARTMENT_NAME, AVG(SALARY), COUNT(COMMISSION_PCT)
FROM DEPARTMENTS
INNER JOIN EMPLOYEES on DEPARTMENTS.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
GROUP BY DEPARTMENT_NAME;
Related
I am having trouble displaying the most people under manager_id. The answer is manager_id = 100 but I can't seem to make a sql that displays it. Below are 2 tables that were created and given to me.
CREATE TABLE departments
( department_id NUMBER(4)
, department_name VARCHAR2(30)
CONSTRAINT dept_name_nn NOT NULL
, manager_id NUMBER(6)
, location_id NUMBER(4)
) ;
CREATE TABLE employees
( employee_id NUMBER(6)
, first_name VARCHAR2(20)
, last_name VARCHAR2(25)
CONSTRAINT emp_last_name_nn NOT NULL
, email VARCHAR2(25)
CONSTRAINT emp_email_nn NOT NULL
, phone_number VARCHAR2(20)
, hire_date DATE
CONSTRAINT emp_hire_date_nn NOT NULL
, job_id VARCHAR2(10)
CONSTRAINT emp_job_nn NOT NULL
, salary NUMBER(8,2)
, commission_pct NUMBER(2,2)
, manager_id NUMBER(6)
, department_id NUMBER(4)
, CONSTRAINT emp_salary_min
CHECK (salary > 0)
, CONSTRAINT emp_email_uk
UNIQUE (email)
) ;
Below is my code where I am trying to join the two tables employees and departments together to find manager_id between them with the most occurrence.
Every time I try to run my sql block it gives me an error like "ORA-00918: column ambiguously defined" or something is wrong with Limit 1
SELECT COUNT(Manager_id) into v_manager_id,
FROM departments d
RIGHT JOIN employees e
ON d.manager_id = e.manager_id
GROUP BY Manager_id
ORDER BY COUNT(Manager_id) DESC
LIMIT 1;
You should rather select count(employee_id) ... group by manager_id so for all employees who are under some manager that count is displayed and then check if that count is max under that manager or not
else it is alias or qualifier issue you should name manager_id as some alias.
this will work:
select manager_id
from (select manager_id,count(*)
from employees
group by manager_id
order by
count(*) desc)
where rownum<=1 ;
you can also use nested subquery like this:
create table ns_231(col1 number,col2 number);
insert into ns_231 values(1,1);
insert into ns_231 values(2,3);
insert into ns_231 values(3,3);
insert into ns_231 values(1,2);
insert into ns_231 values(2,5);
insert into ns_231 values(2,1);
insert into ns_231 values(3,1);
insert into ns_231 values(1,4);
SELECT * FROM ns_231;
commit;
select col1 from (select col1,count(*) from ns_231 group by col1 order by count(*) desc) where rownum<=1 ;
select col1 from ns_231 group by col1
having count(*)=(select max(total) from (select count(*) as total from
ns_231 group by col1));
output:
1
2
for your table the query is :
select manager_id from employees group by manager_id
having count(*)=(select max(total) from (select count(*) as total from
employees group by manager_id));
I think you need to add qualifier to manager_id because it occurs in both tables
SELECT COUNT(d.Manager_id) into v_manager_id,
FROM departments d
RIGHT JOIN employees e
ON d.manager_id = e.manager_id
GROUP BY d.Manager_id
ORDER BY COUNT(d.Manager_id) DESC
LIMIT 1;
CREATE TABLE EMPLOYEES
(
EMPLOYEE_ID NUMERIC(6,0),
FIRST_NAME VARCHAR(20),
LAST_NAME VARCHAR(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL,
EMAIL VARCHAR(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL,
PHONE_NUMBER VARCHAR(20),
HIRE_DATE DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL,
JOB_ID VARCHAR(10) CONSTRAINT "EMP_JOB_NN" NOT NULL,
SALARY NUMERIC(8,2),
COMMISSION_PCT NUMERIC(2,2),
MANAGER_ID NUMERIC(6,0),
DEPARTMENT_ID NUMERIC(4,0),
);
I am new to SQL and my assignment requires me to List the employee details if and only if more than 10 employees are present in department number 50. Following is what I did so far:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE
FROM EMPLOYEES
WHERE DEPARTMENT_ID IN
(SELECT DEPARTMENT_ID
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID
HAVING COUNT(DEPARTMENT_ID) > 10)
But I am not sure how to put the condition DEPARTMENT_ID = 50.
Strictly speaking, you can simply add WHERE DEPARTMENT_ID = 50 within the nested query, but I'm not sure if that's what you what you're getting at because, by filtering on both WHERE DEPARTMENT_ID = 50 and HAVING COUNT(DEPARTMENT_ID) > 10 you're basically saying: "show me all the employees in department 50, but only if there's more than 10 of them, otherwise show me nothing." Is that what you want?
You did the hard part and adding the condition is easy. You can add it to the subquery:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE
FROM EMPLOYEES
WHERE DEPARTMENT_ID IN
(SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE DEPARTMENT_ID = 50
GROUP BY DEPARTMENT_ID
HAVING COUNT(DEPARTMENT_ID) > 10)
I've found similar types of question asked previously.But those are not perfect that what i want.So, I've to asked here.
I've five tables given as bellow...
department(dept_name,building,budget);
primary key (dept_name)
course(course_id,title,dept_name,credits);
primary key (course_id),
foreign key (dept_name) references department
instructor(id,name,dept_name,salary);
primary key (ID),
foreign key (dept_name) references department
section(course_id,sec_id,semester,year,building,room_number,time_slot_id);
primary key (course_id, sec_id, semester, year),
foreign key (course_id) references course
teaches(id,course_id,sec_id,semester,year);
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id, sec_id, semester, year) references section,
foreign key (ID) references instructor
Now I am finding all departments where the total salary is greater than the average of the total salary
at all departments using this query.
with dept_total (dept_name, value) as
(select dept_name, sum(salary)
from instructor
group by dept_name),
dept_total_avg(value) as
(select avg(value)
from dept_total)
select dept_name
from dept_total, dept_total_avg
where dept_total.value >= dept_total_avg.value;
What will be the equivalent query without using the with clause which is provide the same result ?
Finally, I got the correct query.So,the equivalent query without using the with clause will be this.
select dept_name
from (
select dept_name, sum(salary) dept_total
from instructor
group by dept_name
), (
select avg(dept_total) dept_total_avg
from (
select dept_name, sum(salary) dept_total
from instructor
group by dept_name
)
) where dept_total >= dept_total_avg;
I had no change to test but something like this should work.
SELECT dept_name FROM instructor
GROUP BY dept_name
HAVING SUM(salary)>=
(SELECT AVG(dept_sum.SumSalary) AS AvgSalary FROM
(
SELECT dept_name, sum(salary) as SumSalary FROM instructor
GROUP BY dept_name
) as dept_sum
)
Using the HAVING clause will allow this, the following SQL is untested but should work...
SELECT d.dept_name,
SUM(salary) AS DeptTotalSalary,
SUM(salary) / COUNT(*) AS DeptAverageSalary
FROM department d
JOIN instructor i ON i.dept_name d.dept_name
GROUP BY d.dept_name
HAVING DeptAverageSalary > DeptTotalSalary
I am using HR schema,Employees and Departments table. I was asked during the interview following query.
Write a query to print department_name,department_no, count of all employees in corresponding department,but the condition is I can use only one attribute with group by clause.
SQL> desc employees;
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL> desc departments
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
DEPARTMENT_ID NOT NULL NUMBER(4)
DEPARTMENT_NAME NOT NULL VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)
I tried various options to frame query, I used having clause with count(employee_id) but to no effect.Any help appreciated
Since you're getting two values from the same table, and one is the key (or more importantly, unique), you can just apply an aggregate function to the other one:
select d.department_id,
min(d.department_name) as department_name,
count(e.employee_id)
from departments d
left join employees e on e.department_id = d.department_id
group by d.department_id;
SQL Fiddle. Either min or maxof the name would work, and you only need to group by the ID. You could do it the other way around, but name is less likely to be unique.
Not sure if it would count, but as an exercise in futility, you could also just concatenate the values:
select d.department_id ||' '||d.department_name,
count(e.employee_id)
from departments d
left join employees e on e.department_id = d.department_id
group by d.department_id ||' '|| d.department_name;
SQL Fiddle.
You can lpad the department_id to maintain the illusion that they are separate columns, sort of. (It doesn't show up well as a Fiddle though).
Pointless hack, but then it's an interview question so maybe that's appropriate, and seems to just about fulfil the wording you used. Depending on how 'attribute' is defined - I'm taking it to mean a single expression here, which may be a stretch...
I am using oracle's SQL Developer. To begin with, I have this table:
Name Null Type
-------------- -------- ------------
EMPLOYEE_ID NOT NULL NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
DEPARTMENT_ID NUMBER(4)
I would like to retrieve(select) the ID of the department in which are the most employees.
I managed through a statement to retrieve all the numbers of the employees in every department:
select count(employee_id), department_id
from employees
group by department_id;
It gives me something like:
count(employee_id) | department_id
---------------------|------------------
6 100
16 30
1 12
What I would like to do is ONLY to retrieve the department_id 30, which (in this case) has the most employees.
A typical way to do this in Oracle:
select department_id
from (select count(employee_id), department_id
from employees
group by department_id
order by count(employee_id) desc
) t
where rownum = 1;
If you have potential duplicates and want all the department ids, then a join to the max or analytic function is a better approach. For example:
select department_id
from (select count(employee_id), department_id,
rank() over (order by count(employee_id) desc) as seqnum
from employees
group by department_id
) t
where seqnum = 1;