SQL Counting on characters - sql

I want to use an SQL statement that returns the department number, department name and the number of employees for each department that has less than 4 employees grouping by department number and department name. I have inputted sample data
CREATE TABLE dbo.Departments
(
First_Name NVARCHAR(20) NOT NULL,
Last_Name NVARCHAR(20) NOT NULL,
Job_Description VARCHAR(30) NULL,
Department_Name VARCHAR(30) NOT NULL,
Department_Number INT NOT NULL,
Date_Hired DATE NOT NULL,
);
INSERT INTO dbo.Departments(First_Name,Last_Name,Job_Description,Department_Name,Department_Number,Date_Hired)
VALUES
('Niel','Matthews','Sales Representative','Marketing',80,'1990-06-12'),
('Jerome','Daniels','Sales Representative','Accounting',60,'1973-03-30'),
('Caleb','Sewcharran','Employee','Accounting',35,'1986-08-10'),
('Orion','Wolf','Employee','Marketing',80,'1987-10-04'),
('Gaige','Johnson','Employee','Accounting',60,'1992-09-22'),
('Maya','Heller','Employee','Marketing',25,'1989-06-17'),
('James','Maroon','Employee','Accounting',30,'2011-08-22'),
('Alex','Mercer','Employee','Accounting',60,'2010-03-17'),
('Adam','Beecher','Sales Representative','Marketing',80,'2012-10-04'),
('Bruce','Wayne','Employee','Marketing',25,'2012-08-12'),
('Al','Kepler','Sales Representative','Accounting',80,'1973-06-30');
I have also attempted an SQL statement but it does not work
SELECT Department_Number,Department_Name,Job_Description
FROM dbo.Departments
WHERE Job_Description='Employee'
(SELECT DISTINCT Department_Name FROM dbo.Departments,
(SELECT CAST('Marketing'AS INT)AS Least_Employees,
CAST('Accounting'AS INT)AS Least_Least_Employees)AS Least_Employees
WHERE Department_Name>4 OR Department_Name>4)
GROUP BY Department_Name AND Department_Number;
Appreciate it if you would tell me what i could have used to get on the right track.

You can use GROUP BY clause :
SELECT Department_Number, Department_Name, COUNT(*) AS NoofEmp
FROM dbo.Departments d
WHERE ob_Description = 'Employee'
GROUP B YDepartment_Number,Department_Name
HAVING COUNT(*) <= 4;

Related

How to use INSERT INTO SELECT

CREATE TABLE EMPLOYEES (
EMPLOYEEID INT NOT NULL,
DEPARTMENTID INT NOT NULL,
);
CREATE TABLE MANAGERS (
EMPLOYEEID INT NOT NULL,
DEPARTMENTID INT NOT NULL,
ALTER_TIMESTAMP TIMESTAMP NOT NULL
);
I want to insert EMPLOYEES.EMPLOYEEID, EMPLOYEES.DEPARTMENTID, ALTER_TIMESTAMP to MANAGERS table using INSERT INTO SELECT. (ALTER_TIMESTAMP col is current time)
I want this result
enter image description here
this is my code
INSERT INTO MANAGERS
(EMPLOYEEID, DEPARTMENTID, ALTER_TIMESTAMP)
SELECT EMPLOYEEID, DEPARTMENTID, to_char(ALTER_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS:FF3')
FROM EMPLOYEES, DUAL;
but "ORA-00904: "DUAL"."ALTER_TIMESTAMP": invalid identifier"
You have no column named "alter_timestamp" in your table, this is the cause of the error message.
Try the next insert statement:
INSERT INTO MANAGERS
(EMPLOYEEID, DEPARTMENTID, ALTER_TIMESTAMP)
SELECT EMPLOYEEID, DEPARTMENTID, CURRENT_TIMESTAMP
FROM EMPLOYEES;

ORACLE PL/SQL Function is created successfully but the execution body is not working

These are the list of tables I have created and inserted values for the created tables:
CREATE TABLE DEPARTMENT
(DEPARTMENT_ID NUMBER PRIMARY KEY,
DEPARTMENT_NAME VARCHAR(30) NOT NULL
);
CREATE TABLE JOBS
(JOB_ID NUMBER PRIMARY KEY,
JOB_TITLE VARCHAR(35) NOT NULL,
MIN_SALARY DECIMAL NOT NULL,
MAX_SALARY DECIMAL NOT NULL
);
CREATE TABLE EMPLOYEES
(EMPLOYEE_ID NUMBER PRIMARY KEY,
FIRST_NAME VARCHAR(20) NOT NULL,
LAST_NAME VARCHAR(25) NOT NULL,
EMAIL VARCHAR(25) NOT NULL,
PHONE_NUMBER VARCHAR(20) NOT NULL,
HIRE_DATE DATE NOT NULL,
JOB_ID NUMBER NOT NULL,
SALARY DECIMAL NOT NULL,
DEPARTMENT_ID NUMBER NOT NULL,
CONSTRAINT emp_job_fk FOREIGN KEY(JOB_ID) REFERENCES JOBS(JOB_ID),
CONSTRAINT emp_department_fk FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(DEPARTMENT_ID)
);
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(1,'IT');
INSERT INTO DEPARTMENT (DEPARTMENT_ID,DEPARTMENT_NAME)
VALUES(2,'Sales');
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (1,'IT Administrator',250000.00,50000.00);
INSERT INTO JOBS (JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (2,'Salesman',200000.00,40000.00);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (1,'Tony','Starc','starc#gmail.com','0123456789',TO_DATE('15/1/2008','DD/MM/YYYY'),1,45000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (2,'Bruce','Wayne','bruce#gmail.com','0123456788',TO_DATE('15/1/2009','DD/MM/YYYY'),1,40000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (3,'Larry','Ellison','larry#gmail.com','0123456787',TO_DATE('15/1/2010','DD/MM/YYYY'),1,30000.00,1);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (4,'Steve','Jobs','steve#gmail.com','0123456786',TO_DATE('15/1/2011','DD/MM/YYYY'),2,35000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (5,'Remy','Lebeau','remy#gmail.com','0123456785',TO_DATE('15/1/2012','DD/MM/YYYY'),2,30000.00,2);
INSERT INTO EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,DEPARTMENT_ID)
VALUES (6,'Clark','Kent','clark#gmail.com','0123456784',TO_DATE('15/1/2013','DD/MM/YYYY'),2,35000.00,2);
Now in my assignment question, I have been asked to solve the following question:
Write a function called fn_emps_per_dept_jc450912 to retrieve EMPLOYEE_ID,FIRST_NAME,LAST_NAME AND JOB_TITLE with a given DEPARTMENT_ID. This function should have DEPARTMENT_ID as input parameter and this function should have EMPLOYEE_ID,FIRST_NAME,LAST_NAME AND JOB_TITLE as output parameters. It should return TRUE if found and FALSE if not found.
In order to display the information of employees from a particular department, I have written the following function:
CREATE OR REPLACE FUNCTION fn_emps_per_dept_jc450912 (f_dept_id IN NUMBER,f_emp_id OUT NUMBER,f_first_name OUT VARCHAR,f_last_name OUT VARCHAR,f_job_title OUT VARCHAR)
RETURN BOOLEAN
AS
BEGIN
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES,JOBS,DEPARTMENT
WHERE DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
AND JOBS.JOB_ID = EMPLOYEES.JOB_ID
AND EMPLOYEES.DEPARTMENT_ID = f_dept_id;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('Employee not found');
RETURN FALSE;
END fn_emps_per_dept_jc450912;
Function FN_EMPS_PER_DEPT_JC450912 compiled
As you can see from the above that the function has been successfully compiled.
Then I tried executing the function:
DECLARE
f_dept_id NUMBER;
f_emp_id NUMBER;
f_first_name VARCHAR(30) ;
f_last_name VARCHAR(30) ;
f_job_title VARCHAR(30);
f_return BOOLEAN;
BEGIN
f_dept_id := 1;
f_return := fn_emps_per_dept_jc450912(f_dept_id,f_emp_id,f_first_name,f_last_name,f_job_title);
DBMS_OUTPUT.PUT_LINE('Employee_ID: ' || f_emp_id);
DBMS_OUTPUT.PUT_LINE('First Name: ' || f_first_name);
DBMS_OUTPUT.PUT_LINE('Last Name: ' || f_last_name);
DBMS_OUTPUT.PUT_LINE('Job: ' || f_job_title);
END;
I'm getting the following error:
Error report -
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYSTEM.FN_EMPS_PER_DEPT_JC450912", line 5
ORA-06512: at line 10
01422. 00000 - "exact fetch returns more than requested number of rows"
*Cause: The number specified in exact fetch is less than the rows returned.
*Action: Rewrite the query or change number of rows requested
I need the solution code for the execution body to fix this error.
Firstly please use modern join syntax (ANSI standard since 92!).
So your SELECT should be:
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
INTO f_emp_id,f_first_name,f_last_name,f_job_title
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = f_dept_id;
Next when you get a problem like this, you should just run the query in a query window, like this:
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,JOB_TITLE
FROM EMPLOYEES INNER JOIN JOBS ON JOBS.JOB_ID = EMPLOYEES.JOB_ID
INNER JOIN DEPARTMENT ON DEPARTMENT.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID
WHERE EMPLOYEES.DEPARTMENT_ID = 1;
This will reveal the cause of your problem as the output looks like this
EMPLOYEE_ID FIRST_NAME LAST_NAME JOB_TITLE
----------- -------------------- ------------------------- -----------------------------------
1 Tony Starc IT Administrator
2 Bruce Wayne IT Administrator
3 Larry Ellison IT Administrator
I.e the field employees.department_id is not unique. Therefore on execution the stored procedure is trying to put multiple values in a single variable. This it cannot do, hence the error. The procedure compiles ok, because at compile time, the procedure can have no idea that it will be passed a parameter which results in more than one record in the result set.

How to solve single-row subquery returns more than one row

I have an employee table and it contains salary table. I want to give %10 increase to all current employees. I tried to update all employees' salary dates to specific date but I encountered problem with single-row subquery.
My database like this:
CREATE TYPE TEMPORAL_VARCHAR AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART VARCHAR2(50) );
CREATE TYPE TEMPORAL_NUMBER AS OBJECT (
VALID_TIME_LOWER_BOUND DATE,
VALID_TIME_UPPER_BOUND DATE,
VALUE_PART NUMBER );
CREATE TYPE NAME_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE ADDRESS_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE DEPARTMENT_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE MANAGER_TYPE AS TABLE OF TEMPORAL_VARCHAR;
CREATE TYPE SALARY_TYPE AS TABLE OF TEMPORAL_NUMBER;
CREATE TABLE EMPLOYEE (
SSN NUMBER primary key,
NAME NAME_TYPE,
ADDRESS ADDRESS_TYPE ,
BIRTH_DATE DATE,
MANAGER MANAGER_TYPE ,
DEPARTMENT DEPARTMENT_TYPE,
SALARY SALARY_TYPE
)
NESTED TABLE NAME STORE AS NAME_TABLE,
NESTED TABLE ADDRESS STORE AS ADDRESS_TABLE,
NESTED TABLE MANAGER STORE AS MANAGER_TABLE,
NESTED TABLE DEPARTMENT STORE AS DEPARTMENT_TABLE,
NESTED TABLE SALARY STORE AS SALARY_TABLE
;
How to solve this problem? I tried to do this
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
1st it can be duplicate
2nd see sample here
3rd in your code you need bring the where condition into select
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE ssn in (SELECT ssn FROM EMPLOYEE e
WHERE to_date('01.01.2015','mm.dd.yyyy') in (
SELECT VALID_TIME_UPPER_BOUND FROM TABLE(e.salary)
)
)
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = to_date('01.01.9999','mm.dd.yyyy')
test data
INSERT INTO EMPLOYEE(SSN, salary) values (1, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (2, SALARY_TYPE ());
INSERT INTO EMPLOYEE(SSN, salary) values (3, SALARY_TYPE ());
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 1)
VALUES (to_date('01.01.2005','mm.dd.yyyy'), to_date('01.01.2015','mm.dd.yyyy'), 1);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 2)
VALUES (to_date('02.02.2005','mm.dd.yyyy'), to_date('02.02.2015','mm.dd.yyyy'), 2);
INSERT INTO TABLE(SELECT salary FROM EMPLOYEE
WHERE ssn = 3)
VALUES (to_date('03.03.2005','mm.dd.yyyy'), to_date('03.03.2015','mm.dd.yyyy'), 3);
p.s do you really need the complexity?
I solved my problem using iteration like this
BEGIN
FOR employees IN (SELECT SSN FROM EMPLOYEE)
LOOP
UPDATE TABLE(
SELECT E.SALARY
FROM EMPLOYEE E
WHERE E.SSN = employees.SSN
) SAL
SET SAL.VALID_TIME_UPPER_BOUND = '11.16.2015'
WHERE SAL.VALID_TIME_UPPER_BOUND = TO_DATE('12.31.9999','MM.DD.YYYY');
END LOOP;
END;

SQL Server Management Studio: The multi-part identifier could not be bound

I'm taking a SQL class, and on one of the assignments I am asked to create a table with employees, one with projects, as follows:
create table [EMPLOYEE]
(
EmployeeID int identity(1, 1) primary key not null,
FirstName varchar(15) not null,
LastName varchar(15) not null,
Gender char(1) not null,
DOB date not null,
SSN char(9) not null
)
create table [PROJECT]
(
ProjectID int identity(1, 1) primary key not null,
Manager int not null,
PDescription varchar(50) not null,
PStatus varchar(20) not null,
StartDate date not null,
EndDate date not null
)
Where the Manager is the ID of an EMPLOYEE entity. Basically projects are assigned to employees. So, I add some employees and projects
insert into EMPLOYEE (FirstName, LastName, Gender, DOB, SSN)
values ('Chuck', 'Carter', 'M', '07/14/1990', '444556666')
This is the one employee I'm interested in, and in the inserting I'm doing this is the second one, so its EmployeeID would be 2. As for the projects:
insert into PROJECT (Manager, PDescription, PStatus, StartDate, EndDate)
values (2, 'Submit source code for 3D racing game', 'In progress', '01/05/2015', '03/05/2015')
insert into PROJECT (Manager, PDescription, PStatus, StartDate, EndDate)
values (2, 'Test videogame for bugs', 'Not started', '03/05/2015', '05/05/2015')
These two are the ones assigned to the employee above, notice Manager for both is 2, and the EmployeeID of Chuck is supposed to be 2. So, I'm supposed to display the employee name as a full name, combining the first and last name, of those who have been assigned two or more projects (in this case, Chuck).
I wrote this code:
select
FirstName + LastName as FullName
from
EMPLOYEE
where
EmployeeID = PROJECT.Manager and count(PROJECT.Manager) >= 2
But instantly I get this error:
The multi-part identifier "PROJECT.Manager" could not be bound.
Am I supposed to make an inner join to recognize the PROJECT table? But I'm only supposed to display the name of the employee. How can I manage to use the PROJECT.manager column values without displaying them?
Thank you very much in advance.
You have to Join Project table, Add Group by with having clause to filter the Manager
select FirstName +' '+ LastName as FullName
from EMPLOYEE
INNER JOIN PROJECT
on EmployeeID = PROJECT.Manager
group by FirstName +' '+ LastName
Having count(PROJECT.Manager) >= 2

SQL select statement headings

Having trouble working out how to do headings
Display the total number of FEMALE students under the heading 'FEMALE STUDENTS':
Struture:
CREATE TABLE Student
(StudID INTEGER PRIMARY KEY,
StudFName VARCHAR(10) NOT NULL,
StudLName VARCHAR(10) NOT NULL,
DoB DATE NOT NULL,
Sex CHAR(1) NOT NULL CHECK (Sex IN ('M', 'F')),
Email VARCHAR(30) UNIQUE);
SELECT count(Sex) as "FEMALE STUDENTS"
from Student
where sex='F';
You might also try the following:
SELECT COUNT(*) AS "Total Students"
, SUM(DECODE(sex, 'F', 1, 0)) AS "Female Students"
, SUM(DECODE(sex, 'F', 0, 1)) AS "Male Students"
FROM students
I use this method often to get multiple counts as part of one statement.
Use count() function to retrieve the number of rows under a particular column.
Syntax:
SELECT COUNT(column_name) FROM table_name;
In your case the query would be:
SELECT count(sex) from Student where sex='F';
COUNT returns the number of rows returned by the query. You can use it as an aggregate or analytic function.
For more info:
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions032.htm
http://www.w3schools.com/sql/sql_func_count.asp