So I have 2 tables; a task table and an employee table.
A task is created by an employee and maintains the id of the employee that creates it as creator_id.
A task is assigned to an employee and maintains the id of the employee it is assigned to as responsible_id.
The creator of the task and the employee it is assigned to can be different people.
How do I write a select statement that allows me to display the full names of both the employee that created the task and the employee that is assigned to it.
I think it might look something like this:
SELECT Task.Description, Employee1.name, Employee2.name
FROM Task, Employee Employee1, Employee Employee2
WHERE Task.creator_id = Employee1.id
AND Task.responsible_id = Employee2.id;
I have tried variations of this but it either returns errors or hits the memory limit.
Where am I going wrong?
From your description the query is correct but you should consider rewriting it to use explicit ANSI joins:
SELECT Task.Description, Employee1.name, Employee2.name
FROM Task
JOIN Employee Employee1 ON Task.creator_id = Employee1.id
JOIN Employee Employee2 ON Task.responsible_id = Employee2.id;
Sample SQL Fiddle
Related
Sorry for my bad english. I have two tables: tblemployees (employeeid) and tbloffices: officeid,employeecode,activeposition
Basically, tbloffices contains list of offices in a company the employee has ever worked in. He/she can work only in one office at a given time (so activeposition can be 1 only per employee once). Some employees can have record in tbloffices but with no active office currently. Some employees might not have a record in tbloffies at all (waiting for relocation for e.g.).
My query needs is: return employeeid along with the activeposition=1 if it exists. Else, return the latest position. If no records exist, return NULL of course:
I tried the following query:
SELECT employeeid, officeid, activeposition
FROM tblemployees
LEFT
JOIN tbloffices
ON(tbloffices.employeecode = tblemployees.employeeid)
GROUP
BY employeeid
The query does work for rows with no reference in tbloffices. How do i return one record per employee in the fashion I want? I already tried:
(officeid is NULL OR activeposition=1)
but that fails for employees with record but no active position.
I have a list of employees and with a list of immediate supervisors in the table. I want to create a select statement (I am limited because I am not using SQL Server directly just it as an engine) that not only produces the immediate supervisor but a supervisors supervisor in the next column. I have titles but I want to create one that is not limited by titles and or levels of management. Even just suggestions to try would be helpful.
This is how I started (the were clause is just so I can test data). I plan on flipping it too a two column select statement. I am not sure
SELECT PayeeID, tblLevel1.Sup1, Sup2
From (SELECT PayeeID ,SupervisorID AS Sup1
FROM PayeeHRAttribute
Where AsOfDate ='10/31/2015') AS tblLevel1 Right Join (Select PayeeID as Sup1, SupervisorID AS Sup2
FROM PayeeHRAttribute
Where AsOfDate = '10/31/2015') AS tblLevel2 On tblLevel1.Sup1 = tblLevel2.Sup1
Create 2 queries in Report Studio (look into Queries tab) and join them.
First table
supervisor
employee
Second table
supervisor as supersupervisor
employee as supervisor
Join it by supervisor field.
Create list with fields
employee
supervisor
supersupervisor
update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
where a.job_role='MAN1';
OK I have a table of all of our employees - around 100K.
All of our users have job roles that I built based on their employee.job_title. So based on 4K+ job_titles I knock that down to about 40 job_roles. This is so we can assign things in our CMS based on employee.job_roles. This has been working good but the problem is with the managers. The managers get some generic corporate job_title that we role into a generic job_role.
What you see above is code that I use to kind of do what I need to do - find out what job_role a supervisor based on what "most of their employees do". This outputs the correct sup_role but there are several things wrong with my code:
based on my syntax it won't let me update the employee table directly. I have have to update an employee "helper" table and fill in later.
So it is parsing through for the job_role "MAN1". First I don't want to update this to add new manager job roles. Also this doesn't account for my company doing ad hoc things like a manager just have a regular job title or different NULL fields.
And then the last part is that this code is taking 6 minutes to go through. Luckily I run this as a batch job but I am afraid it might cause crashes.
So I have the following table -
employee
with applicable fields
employeeid
supervisorid
job_title
job_role
sup_role
So below is my last attempt. It just runs and never outputs anything. I am wondering if I need to create a helper table to grab the DISTINCT supervisorid's since one employee could be many people's supervisor.
update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
WHERE a.uid IN (select DISTINCT employee.supervisorid
from employee
where employee.supervisorid is not null
);
I'm far from being a database expert, so please feel free to let me know I'm doing it entirely wrong. I'm trying to create a set of tables that has the following basic rules:
There are companies, managers and employees. Managers can only belong to one company, but employees can belong to more then one manager. The table structure I've come up with is something like this:
# Companies
company_id
company_name
# Managers
manager_id
company_id
# Employees
employee_id
company_id
employee_name
# Managed By
employee_id
manager_id
Does this structure seem reasonable? I thought I need something like "Managed By" since an employee can have multiple managers.
What I'm boggling on is now how do I manage to grab the records I'd want. For example:
Get all employee names belonging to a certain manager
Get all employee names belonging to two certain managers
All employees to the same company
edit: I think I'm getting the queries figured out but this still feels unweidy, so any help on the table structure would be appreciated.
The fact I'm having problems writing queries for this information makes me think I've done something fundamentally wrong with the table structure. Hopefully someone here can set me right?
Generally, the scheme is correct. The one possibility that does exist, however, is that you could have data where an employee is managed by managers at more than two companies.
For your queries:
select distinct Employees.employee_name as name from Employees, Managers, ManagedBy where Managers.manager_id = X and ManagedBy.manager_id = Managers.manager_id and Employees.employee_id = ManagedBy.employee_id;
and
select distinct Employees.employee_name as name from Employees, Managers, ManagedBy where (Managers.manager_id = X or Managers.manager_id = Y) and ManagedBy.manager_id = Managers.manager_id and Employees.employee_id = ManagedBy.employee_id;
where X and Y are the manager IDs you want.
edit: I know you crossed out the queries you wanted, but the third one is this:
select distinct Employees.employee_name as name from Employees where Employees.company_id = Z;
where Z is the company ID you want.
All employees to the same company
SELECT employee_id, employee_name, company_name
FROM Employees
LEFT JOIN Companies ON Employees.company_id = Companies.company_id
WHERE Companies.company_id = ????
or if you pulling by name
WHERE Companies.company_name = 'ABC'
Get all employee names belonging to a certain manager
SELECT employee_id, employee_name, manager_id
FROM Employees
LEFT JOIN Managed_By ON Employees.employee_id = Managed_By.employee_id
WHERE Managed_By.manager_id = ????
manager_name in Managers table would be nice to have
I have a bunch of records (orders) that I want to make available to users to make reports from.
The users come from different departments, and I would like to make it, so each department can only see their own stuff.
I can't figure out how to do this the right way.
What I have now is:
- A model where I have placed a Filter on the Order table.
The filter can use GetUserID() to get the users name, but I can't figure out how I get from that to the "UserDepartment" table that maps users to specific departments.
Ofcourse, I would prefer a solution whereby I didn't have to create new access groups or edit the model for each department that someone might dream up.
Any clues?
(Using SQL server 2008)
EDIT: This link http://blogs.msdn.com/bobmeyers/articles/Implementing_Data_Security_in_a_Report_Model.aspx shows the basics of what I'm trying to do, but the author seems to assume that each record have a UserName field that can be matched.
In my case i want all users of department X to be able to access the line.
We had a similar problem to this and ended up writing a function in SQL.
The function did the following:
Received the username parameter from SRSS
Performed a lookup on the permissions table and retrieved the records (department Id's in your case).
returned the department Id's
Then our sql statement looked like this:
SELECT *
FROM ImportantData
WHERE DepartmentId IN (SELECT Id FROM fn_GetUserDepartmentAllocations(#UserName))
This did force us to modify all of the sql queries but it allowed us to do it with minimal complex logic.
The other thing that this allows for is if you have one user who transcends department boundaries: for example a manager of 2 departments.
CREATE FUNCTION [dbo].[fn_GetUserDepartmentAllocations]
(
#UserName NVARCHAR(100)
)
RETURNS
#TempPermissions TABLE
(
DepartmentId Int
)
AS
BEGIN
INSERT INTO #TempPermissions
SELECT DepartmentId
FROM DepartmentPermissions
WHERE DepartmentAllowedUsername = #UserName
RETURN
END
The main benefit to doing it this way is it also allows you to edit one place to change the entire permissions structure, you don't have to go through each and every report to change it, instead you change one place
For example you could have a manager who belongs to 2 departments but is not allowed to view them except on thursdays (I know silly example but you get the point hopefully).
Hope this helps
Pete
This assume that Users have Orders.
So, filter by users who exist in the same dept as the filter user. Don't filter orders directly.
I've guessed at schema and column names: hoep you get the idea...
SELECT
MY STuff
FROM
Order O
JOIN
UserDept UD ON O.UserCode = UD.UserCode
WHERE
EXISTS (SELECT *
FROM
UserDept UD2
WHERE
UD2.UserCode = #MYUSerCode
AND
UD2.DeptID = UD.DeptID)
--or
SELECT
MY STuff
FROM
Order O
JOIN
UserDept D ON O.UserCode = D.UserCode
JOIN
UserDept U ON D.DeptID = U.DeptID
WHERE
U.UserCode = #MYUSerCode
What you're trying to achieve is difficult using the GetUserID() method. To use that your source query would have to return a lot of redundant data, imagine something like the following:
/*
Table: User
Fields: UserID, LoginName, FullName
Table: Department
Fields: DepartmentID, Name
Table: UserDepartments
Fields: UserID, DepartmentID
Table: Order
Fields: OrderNumber, DepartmentID
*/
SELECT O.OrderNumber, O.DepartmentID, U.LoginName
FROM Order O
JOIN Department D ON D.DepartmentID = O.DepartmentID
JOIN UserDepartments UD ON UD.DepartmentID = D.DepartmentID
JOIN User U ON U.UserID = UD.UserID
This will give you more rows than you want, basically a copy of the order for each user in the department that owns the order.
Now you can apply your filter as described in the link you provided. This will filter it down to just one copy of the order rows for the current user if they're in the right department.
If this is a performance issue there's other alternatives, easiest being using a local report (.RDLC) in either ASP.NET, WinForms or WPF and passing user details off to the data call so the filtering can be done in the SQL.