When I write this query in sql plus show me error (ORA-00998: must name this expression with a column alias)
create or replace view vw_salary as select dname ,
(select count(*) from employee where dno=department.dnumber) from department;
Columns in a view need to have a name. So, you need as after the subquery:
create or replace view vw_salary as
select dname,
(select count(*) from employee e where e.dno = d.dnumber
) as NumEmployees
from department d;
I strongly encourage you to use table aliases and qualified column names (that is use the table alias). This is particularly important for correlated subqueries, where it is easy to make a mistake and that is hard to debug.
I also note that the view is called vw_salary, but there is no salary information.
select department.dname, count(employee.dno) as empCount
from department
left join employee
on employee.dno = department.dnumber
group by department.dname
I think this will be more efficient than your current format
It means you need to name the count expression ... try the following, you can change "TheCount" to any name you want to use.
create or replace view vw_salary as select dname ,
(select count(*) AS TheCount from employee where dno=department.dnumber) from department;
Related
I have a dept --< emp schema. I want create a resultset which joins dept and emp with a row for each dept and a column which is an array of emps in each dept.
So something like select dept_name, xxxxxxx from dept,emp where emp_dept_id = dept_id
returning
department1 | fred,bill,joe
department2 | faith, hope, charity
I would recommend arrays:
select d.dept_name, array_agg(e.name)
from dept d join
emp e
on e.emp_dept_id = d.dept_id
group by d.dept_name;
You can also use string_agg(e.name, ',') if you really prefer a string.
Notes:
Never use commas in the FROM clause.
Always use proper, explicit, standard, readable JOIN syntax.
Qualify all column names in a query that references multiple tables.
Use table aliases so the query is easier to write and read.
I need to create a query that shows the last name of an employee, the employee id, the last name of the manager of that employee and the id of that manager.
The last name, id, and the manager id of that employee is easy to do because it is already in one row, which means that the following is sufficient:
SELECT last_name, employee_id, manager_id FROM employees WHERE manager_id IS NOT NULL;
But to get the last_name of the manager, you have to search the same table by the manager id you got from the employee. The solution I found is:
SELECT last_name,
employee_id,
(SELECT last_name FROM employees WHERE employee_id = manager_id),
manager_id
FROM employees
WHERE manager_id IS NOT NULL;
However, it seems that 'manager_id' doesn't work in the subquery (although I expected that) and the output is NULL (for the manager id, all the other columns do have values).
So my question is, how can I use the manager_id in the subquery?
Side note: The manager_id can be different for each employee, so using a constant value doesn't work.
What you need is a correlated subquery. I strongly, strongly recommend that you use table aliases and qualified column names in all your queries. However, these are particularly important with correlated subqueries.
You should write this query as:
SELECT e.last_name, e.employee_id,
(SELECT m.last_name
FROM employees m
WHERE m.employee_id = e.manager_id
),
e.manager_id
FROM employees e
WHERE e.manager_id IS NOT NULL;
The alias e is an abbreviation for the table reference to employees in the outer query. The alias m is an abbreviation for the table reference in the subquery.
Notice that all column references use the table alias. This makes the query unambiguous, can prevent unexpected errors, and makes the query much easier for you and others to understand.
You could use a self inner join ( a join with the same table)
SELECT
a.last_name
, a.employee_id
, b.last_name
, a.manager_id
FROM employees a
INNER JOIN employees b ON b.employee_id = a.manager_id;
The inner join work only if a.manager_id is not null so you can avoid this where condition
When you want to refer to a table in the outer query, you need to either use the full table name like table.field or, as in your case, if the outer query table is same as the subquery table, you need to assign an alias to the outer query table and use it in the subquery like this:
SELECT
last_name, employee_id,
(SELECT last_name FROM employees WHERE employee_id = emp_outer.manager_id),
manager_id
FROM employees emp_outer
WHERE manager_id IS NOT NULL;
I have table
EMP(id int primary key, name varchar2(15), mgrID int).
Now this table contain all employees(including worker and manager) in company. mgrID column contain id of employee to whom they are reporting.
I want to list the name of worker who is not manager along with their name of manager.
What to do for such query.
I tried nested select query as follows:
select name, (select name from EMP where mgerID is NULL)
as Manager from EMP;
Will this query give proper result?
You could use a self-join:
SELECT e.name AS name, m.name AS manager_name
FROM emp e
JOIN emp m ON e.mgrid = m.id
Your query should fail because you sub-query is uncorrelated and will return multiple results if you have multiple top-level managers.
select name
, (select name from EMP b where b.ID = a.mgerID ) as Manager
from EMP a;
I think the self-join is the more canonical solution, but you should understand the correlated subquery as well as it has many application.
imagine I have two tables, the "departments" table and the "employee" table.
This employee table has a column for "category".
I'd like to make a query for selecting departments that only have a specified type of employees.
Thank you.
You will need to perform a join from your departments and employee table on whatever columns link these two tables together. In the where clause, you will specify what types of employees that you want.
This will return a row for each employee, which might not be what you want. You may use the distinct function on the important columns that you're looking for in the departments table to get the final answer.
select distinct dept_id
from employee
where category = 'cat1'
and dept_id not in (select distinct dept_id
from employee
where dept_id <> 'cat1');
SELECT dept_id
FROM departments
WHERE dept_id NOT IN
(SELECT DISTINCT dept_id
FROM employee
WHERE category_id != #specified_category)
This query assumes there are no departments with no employees, since it will also return those empty departments. If that's a problem, you can add:
AND dept_id IN (SELECT distinct dept_id FROM employee)
Select d.id_department from departments d where not exists
(Select e.id_employee from employees e where e.category!=your_category and e.id_department=d.id_department) you also need to verify that department has employees.
I have two table in Access, Employee and Dept.
In Employee table there is empname column and deptcode column, while in Dept table there is deptcode column and deptname column.
I want to do a query which shows empname, deptcode and deptname in a new table. I have tried:
SELECT empname, deptcode, deptname
FROM employee,dept
And it cannot work as the deptcode exist in both table and it creates error. Can anyone kindly tell me how to solve this error problem?
You need to alias your tables in the FROM clause and then use the table alias in the SELECT statement.
select e.empname,d.deptcode,d.deptname
from employee e
inner join dept d
on e.deptcode = d.deptcode;
You just need to associate the columns with the tables in the form of aliases or table name itself. Something like this should work.
select employee.empname,
dept.deptcode,
dept.deptname from employee,dept
where employee.deptcode = dept.deptcode;
Note that I have added a condition to match the department code for the employees