Create table error oracle - sql

I am getting an error: ORA-01789: query block has incorrect number of result columns
when trying to create a table from data in 2 other tables. Please help, is this just a syntax error or am I combining the tables in the wrong way?
CREATE TABLE EMPDATA(ID, NAME, SALARY, DEPTNAME)
AS
SELECT e.employee_id, (e.first_name || e.last_name), e.salary
FROM employees e
UNION
SELECT d.department_name
FROM departments d;

I think you want JOIN instead of UNION:
CREATE TABLE EMPDATA(ID, NAME, SALARY, DEPTNAME)
AS
SELECT e.employee_id, (e.first_name || e.last_name), e.salary, d.department_name
FROM employees e
JOIN departments d on(d.department_id = e.department_id);

The number of coumns while using UNION should be same in the SELECT statement

You need to join to set the department and not union
CREATE TABLE EMPDATA(ID, NAME, SALARY, DEPTNAME)
AS
SELECT e.employee_id, (e.first_name || e.last_name), e.salary, d.department_name
FROM employees e
JOIN departments d on d.id = e.department_id
You might need to adjust the column names of the join condition since you did not mention the relation.

Your select query returns three columns, for the table you want four. union does union the results of queries, but they have to have same number and types of columns. Your second query has one column, first - three.

When you create a table from a subquery, the resulting columns must be of the same type and number of columns as the subquery.
It is not worth having an EMPLOYEE_ID column of type NUMBER in the DDL and having the column EMPLOYEE_ID of type DATE for example.
Maybe the column exists in the DDL and the subquery DOES NOT EXIST.
in your example you try to have the column DEPTNAME in the DDL, but in the subquery that column does not exist in the table EMPLOYEES,
If you want to have the column DEPTNAME, you have to do a JOIN with the table DEPARTMENTS.
Remaining as follows:
CREATE TABLE EMPDATA (ID, NAME, SALARY, DEPTNAME) AS
   SELECT e.employee_id, (e.first_name || e.last_name), e.salary, d.department_name
   FROM employees e,
        departments d
WHERE 1 = 1
AND d.department_id = e.department_id;
In my BLOG I have an article that talks about the DDL CREATE TABLE statement in ORACLE SQL, I'll share it for you.
There I talk about a little more things, like creating primary, foreign, insert, etc. klaves.

Related

How to `insert into` with select using `group by` and having a unique constraint key in Oracle?

I am trying to insert into a table, 5 values from other 2 tables, but when I
try to insert them, Oracle sends me a message that I am violating the unique key restriction, what I do not understand why I have this problem if I am using the distinct clause in the select.
Thanks
My query:
insert into grados_salariales (Department_id,
Department_name,Sumatoria,Sal_minimo,Sal_maximo)
Select distinct departments.department_id,
departments.department_name,
sum(employees.salary),min(employees.salary),
max(employees.salary)
from employees,departments
group by salary,department_name,
departments.department_id;
This is the table that already exist and the unique key statement
create table
grados_salariales(
Department_id number,
Department_name varchar(50),
Sumatoria number,
Sal_minimo number,
Sal_maximo number);
Alter table grados_salariales
add constraint Department_id_pk
primary key ( Department_id);
I would expect inserting the department_id without problems.
This is your query:
select distinct d.department_id, d.department_name,
sum(e.salary), min(e.salary),
max(e.salary)
from employees e join
departments d
on e.department_id = d.department_id
group by e.salary, d.epartment_name, d.department_id;
The problem is the salary in the group by. If you want one row per department, then you can do:
select d.department_id, d.department_name,
sum(e.salary), min(e.salary),
max(e.salary)
from employees e join
departments d
on e.department_id = d.department_id
group by d.department_name, d.department_id;
Notes:
Never use commas in the FROM clause.
Always use proper, explicit, standard JOIN syntax.
Use table aliases so your queries are easier to write and read.
SELECT DISTINCT is almost never appropriate with GROUP BY.

How do I use a value from the superquery inside a subquery?

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;

Group by clause always produces error "Not a group by expression"

I have two tables
EMPLOYEES(employee_id,first_name,last_name,salary,manager_id,department_id)
and
DEPARTMENTS(department_id,department_name,manager_id)
When I try to create a new table "EMP_DEPT" which contains
department_id ,department_name, dcount(count of employees in each department),
dtotal(total salary of employees in each department),
dmaxsal(maximum salary in a department), dminsal(minimum salary in a department)
it shows ORA00979: not a GROUP BY expression
I did this in oracle
create table emp_dept as(select e.department_id,d.department_name,count(*),sum(salary),max(salary),min(salary)
from employees e,departments d where e.department_id= d.department_id
group by e.department_id);
You seem to be a bit confused in writing your query.
First of all, You are using aliases in columns of table departments, but you're not using aliases in columns of table employees.
select e.department_id,d.department_name,count(*),sum(salary),max(salary),min(salary)
from employees e,departments d
Secondly, you're using a where clause, but shouldn't a left join be a better choice?
where e.department_id= d.department_id
Thirdly, and most importantly, you're doing group by in e.department_id, whereas it should be d.department_id , since there is a parent-child relationship among the tables departments and employees. I don't know how you designed your table, but logically, department_id is supposed to be the primary key in departments table, and foreign key in employees table. That's why, group by e.department_id is incorrect.
Therefore,
group by e.department_id
Should instead be,
group by d.department_id
I think you just need to modify your query in the following way:
create table emp_dept as
(select d.department_id,d.department_name,count(e.*),
sum(e.salary),max(e.salary),min(e.salary)
from departments d
left join employees e
on e.department_id= d.department_id
group by d.department_id);
And hopefully it will fix your problem.

Specified Departments? - SQL

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.

find the link in tables sql exercise

so I'm stuck on this question where it says:
write a query to retrieve a list of ALL departments in alphabetical order containing the columns DEPARTMENT_ID , DEPARTMENT_NAME , LAST_NAME , FIRST_NAME where last_name and first_name are the name of the Manager of the Department wherever there is one.
I'm have the HR database using the departments, employees table what i have written so far is:
select department_id, department_name, e.last_name, e.first_name
from departments d, employees e
where e.department_id=d.department_id
and d.department_id=e.department_id
and d.manager_id=e.manager_id
having department_name = '%Manager%';
yet i can't figure it out, any tips will help thanks!
A having clause relates to a group by. Where you have no group by, there is no meaning for a having clause.
You just need your join to get the record in the employees table for the manager.
select department_id, department_name, e.last_name, e.first_name
from departments d, employees e
where d.manager_id=e.id
Better is to use the newer join syntax,
select dept.department_id, dept.department_name, emp.last_name, emp.first_name
from departments dept
inner join employees emp on dept.manager_id = emp.id
You don't need conditions for e.department_id=d.department_id and d.department_id=e.department_id, (for one thing these are redundant, so you would only need one if they were needed) because the employees.department_id field refers to the department the employee is in, and what you want is the manager employee record for the department. The manager employee record for the department is represented as the foreign key to the primary key of the employee table.
this might help you...
`select e.first_name,e.last_name,d.department_id ,d.department_name from employees e,departmets d where d.manager_id=e.employee_id order by d.department_name;`