Need help understanding a Simple SQL query to retrieve data - sql

I am having trouble creating a SQL query that will list the names of manager(s) whose employee(s) handle less than two orders.
Here is a picture of the database, I tried to put an output of the database, but had trouble.
http://s22.postimg.org/spou700b5/printout.jpg

SELECT O.Name
FROM Employee E
JOIN Employee O ON O.EmployeeID = E.ManagerID
LEFT OUTER JOIN OrderT T ON T.EmployeeID = E.EmployeeID
GROUP BY O.Name
HAVING COUNT(T.OrderID) < 2

Related

To create a view using 5 tables with all columns of all tables

I have to create a view that joins together all of the columns in the CUSTOMERS, ORDERS, ORDERDETAILS, EMPLOYEES, PAYMENTS and PRODUCTS tables.
the schema for the table is below
I tried the following query, though I am at a loss how to solve the above question :
create view orders_view AS
select *
from sys.customers c
left JOIN EMPLOYEES e
on c.SALESREPEMPLOYEENUMBER = e.EMPLOYEENUMBER
left join sys.orders o
on c.CUSTOMER NUMBER = o.CUSTOMERNUMBER
left join sys.orderdetails od
on o.ORDERNUMBER = od.ORDERNUMBER
left join sys.products p
on od.PRODUCTCODE = p.PRODUCTCODE
left join sys.PAYMENTS py
on c.CUSTOMERNUMBER = py.customernumber
I am a newbie with SQL and databases, so any help is appreciated.
Here are some observations on things going wrong:
You have curly braces that are not necessary (perhaps this is a typo in the question).
You are selecting *, but have duplicate column names (such as productcode), which prevents the view from being created. Best practice: list all the columns explicitly in the view.
You have c.CUSTOMER NUMBER = o.CUSTOMERNUMBER. The space is probably a typo. If not, change the name so the space is not part of the name. Best practice: Use identifiers that do not have to be escaped.
I am not aware of a sys.customers table. The sys schema should only be used for internal Oracle objects. (Here is one source.)
thank you for all the inputs. they helped me a lot in figuring out the answer.
Following is the query for the question asked above.it gave me a view with columns from all tables.
create or replace view overall AS
select c.*,
e.LASTNAME,
e.FIRSTNAME,
e.EXTENSION,
e.EMAIL,
e.OFFICECODE,
e.REPORTSTO,
e.JOBTITLE,
o.ORDERNUMBER,
o.ORDERDATE,
o.REQUIREDDATE,
o.SHIPPEDDATE,
o.STATUS,
o.COMMENTS,
od.PRODUCTCODE,
od.QUANTITYORDERED,
od.PRICEEACH,
od.ORDERLINENUMBER,
p.PRODUCTNAME,
p.PRODUCTLINE,
p.PRODUCTSCALE,
p.PRODUCTVENDOR,
p.PRODUCTDESCRIPTION,
p.QUANTITYINSTOCK,
p.BUYPRICE,
p.MSRP,
py.CHECKNUMBER,
py.PAYMENTDATE,
py.AMOUNT
from sys.customers c
left JOIN EMPLOYEES e
on c.SALESREPEMPLOYEENUMBER = e.EMPLOYEENUMBER
left join sys.orders o
on c.CUSTOMERNUMBER = o.CUSTOMERNUMBER
left join sys.orderdetails od
on o.ORDERNUMBER = od.ORDERNUMBER
left join sys.products p
on od.PRODUCTCODE = p.PRODUCTCODE
left join sys.PAYMENTS py
on c.CUSTOMERNUMBER = py.customernumber
;
Your query looks alright, but I don't think it will let you create a view if more than one column has the same name.
Since there are duplicates, e.g. CITY, I think the only way around it is to name all the columns and give unique names for duplicate columns.

inner join vs stored procedure or Function sql server

I have this schema :
When I want to display the Attend table, instead of DoctorId and PatientId, Employee Name And Patient Name display.
Like this:
id
Patient name
Doctor Name [== Employee name]
Start
End
First way is to use an inner join :
select
a.Id, p.Name, a.Name, a.Start, a.End
from
Patient as p
inner join
(select
e.Name, at.Id, at.Start, at.End, at.PatientId
from
Attend as at
INNER JOIN
Employee as e on at.DoctorId = e.Id) as a on p.Id = a.PatientId
Second way is to use a function or stored procedure - send in the id and get back name
select
a.Id,
FindDoctor(a.DoctorId) as Doctor,
FindPatient(a.PatientId) as Patient,
a.Start, a.EndTime
from
Attend AS a
Which is the better? Which is the optimized approach?
In general, SQL engines do a better job of optimizing queries than of optimizing function calls. I would suggest that you stick with the query, at least at first. This also makes it easier to understand performance issues that might arise.
By the way, there is no need for a subquery for what you want to do. SQL Server is pretty smart, so it probably doesn't affect performance. However, you can write the query as:
select at.Id , p.Name , e.Name , at.Start, at.End
from Patient p inner join
Attend at
on p.Id = at.PatientId inner join
Employee as e
on at.DoctorId = e.Id;
Some people like to embed such queries in stored procedures. If you want to encapsulate this logic, I would suggest a view or table-valued function instead.

SQL relation between 3 tables

I need some help with an SQL statement...
I have tree tables
Problems
Solutions
Employees
The Problem table contains an ID, a description of the problem and the ID of the person who reported it.
The Solution table contains an ID, description of the solution and the ID of the person who solved the problem.
The Employee table contains an ID, the first and last names of all the employees of a company.
The ID of the solver and the reporter are related to the ID of the employee
I want to write a query that gives me the description of the problem and the solution and the first and last name of the employee who reported and solved it.
This is the query I have to select everything I need except the name of the solver..
SELECT
P.ProblemID,
P.Description AS ProblemDescription,
P.SolutionID,
P.ReporterID,
E.FirstName,
E.LastName,
S.SolverID,
S.Description AS SolutionDescription
FROM
(tblProblem P
LEFT OUTER JOIN
tblEmployee E ON P.ReporterID = E.EmployeeID)
LEFT OUTER JOIN
tblSolution S ON P.SolutionID = S.SolutionID;
I really hope someone can help me with this..
Thanks in advance!
Just join the employee table again, once for the solver and once for the reporter:
SELECT P.ProblemID,
P.Description AS ProblemDescription,
P.SolutionID,
P.ReporterID,
RE.FirstName as ReporterFirstname,
RE.LastName as ReporterLastname,
S.SolverID,
S.Description AS SolutionDescription,
SE.FirstName as SolverFirstname,
SE.LastName as SolverLastname
FROM
((tblProblem P LEFT OUTER JOIN
tblEmployee RE ON P.ReporterID = RE.EmployeeID) LEFT OUTER JOIN
tblSolution S ON P.SolutionID = S.SolutionID) LEFT OUTER JOIN
tblEmployee SE ON P.ReporterID = SE.EmployeeID
PS: I saw you using parentheses. Are you using Access? If so, I hope I got them right.
You need to join on the employee marked as the solver as well. Following your style and not knowing your exact column names:
SELECT
P.ProblemID,
P.Description AS ProblemDescription,
P.SolutionID,
P.ReporterID,
E.FirstName,
E.LastName,
S.SolverID,
S.Description AS SolutionDescription,
E2.FirstName as SolverFirstName,
E2.LastName as SolverLastName
FROM
(tblProblem P LEFT OUTER JOIN
tblEmployee E ON P.ReporterID = E.EmployeeID)
LEFT OUTER JOIN
tblSolution S ON P.SolutionID = S.SolutionID
LEFT OUTER JOIN
tblEmployee E2 ON S.SolverID = E2.EmployeeID;

How do I compose this sql query in Oracle?

I have got an sql query that pulls out all sorts of information. Part of it is the following
select gsm.mobile_no, emp.employee_id, d.department_id
from data gsm, employees emp, department d
where gsm.code = e.code
and d.id = e.id
Now there's a column called roaming in another table called "call" . Here's the problem. There's information from the call table for only some of the mobile numbers so when I join gsm.code = call.id like below
select gsm.mobile_no, emp.employee_id, d.department_id, roaming.name
from data gsm, employees emp, department d, call roaming
where gsm.code = e.code
and d.id = e.i
and roaming.id = gsm.code
Then I lose information about employees and departments since only the records that satisfy the condition roaming.id = gsm.code are retrieved so I lose info about departments, employees and all other mobile numbers. I want to retrieve all records from all tables including roaming.id for the mobile numbers where applicable and if there's no data available for some of the mobile numbers then display null but I want all of the records displayed.
How could I do that?
Your time has come to move to the world of modern join syntax. Put your join conditions in the on clause and remember the simple rule: Never use a comma in the from clause.
What you need is a left outer join. You can't really do that in the where clause. Well, you can in Oracle, but it is not pretty and not as good as a real left outer join.
select gsm.mobile_no, emp.employee_id, d.department_id, roaming.name
from employes left outer join
data gsm
on gsm.code = e.code left join
department d
on d.id = e.i left outer join
call roaming
on roaming.id = gsm.code;
Although you can mix inner and outer joins, you want to keep all employees. So start with that table and make all the joins left outer join.

Calculate Percentage Of Certified Managers

I asked a similar question a few weeks ago, but now the requirements have changed.
Considering the following tables:
http://www.maroisconsulting.com/Temp/query.png
I need to create a query that returns the percentages of employees who are managers (Titles.IsManager) and who have a date in the Certified field (Employees.Certified). The results need to be grouped by the Group each store is in.
So far I have this:
SELECT d.GroupId,
Sum(d.cert_complete) AS SumOfcert_complete,
Count(d.cert_complete) AS CountOfcert_complete
FROM (SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
) AS d
WHERE t.IsManager
GROUP BY d.GroupId;
And then this
SELECT q.GroupId,
(SumOfcert_complete/CountOfcert_complete)*100 AS percent_certified,
Groups.GroupName
FROM qryGroupCert_base AS q
INNER JOIN Groups ON q.GroupId = Groups.GroupId;
You can see in the first query where I added the Titles table.
1) I get prompted for the IsManager, although I don't know why
2) The results coming back are not different than before I added the IsManager
Anyone see what's wrong here?
Many thanks
Within your first query, you have this subquery which includes Titles aliased as "t":
(SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
) AS d
Then, after the definition of the subquery, you have this WHERE clause:
WHERE t.IsManager
The problem is the "t" alias and IsManager column only exist within the the subquery --> they are unknown to the outer (parent) query. In cases where the Access database engine encounters something it doesn't recognize as an object name, function, literal value, or SQL keyword, it thinks that something must be a parameter ... so pops up the input box asking you to provide a value for the (IsManager) parameter.
I think you should move the WHERE clause inside the subquery definition.
SELECT d.GroupId,
Sum(d.cert_complete) AS SumOfcert_complete,
Count(d.cert_complete) AS CountOfcert_complete
FROM [SELECT DISTINCT
s.GroupId,
e.EmployeeID,
IIf(e.Certified Is Null,0,1) AS cert_complete
FROM
((Stores AS s
INNER JOIN EmployeeStores AS es ON s.StoreId = es.StoreId)
INNER JOIN Employees AS e ON es.EmployeeId = e.EmployeeID)
INNER JOIN Titles AS t ON e.TitleId = t.TitleId
WHERE t.IsManager = True
]. AS d
GROUP BY d.GroupId;
Perhaps you need to supply a criteria for t.IsManager, such as t.IsManager = TRUE. If the where clause doesn't have a value to set it equal to, Access probably isn't resolving it to the actual column, but thinks it's a query parameter.