Select rows depending on field value - sql

I have 2 tables: Employee and Appointments.
1 Employee can have multiple Appointments.
There is a field: Visibility which can hold 0, 1 or 2.
0: show any of the appointment,
1: Show this appointment only,
2: Don't show the appointment.
Now i want to select the records of employee and appointments:
if visibility is 1 then select that record and not any other records
if visibility is 0 then select just a record, like the top 1
if visibility is 2 then select nulls for that record, except the employee id.
can anyone point me out how it can be done using Sql Server 2000?

I'm making a couple of assumptions.
Its possible to have more than one appointment
If you have an appointments with 1 and 0 you want to Guarantee the one with 1 is shown
You can only have one record with 1
SELECT
e.empid,
COALESCE(OneAppoint.appointmentID, ZeroAppoint.appointmentID) appointmentID
FROM
employee e
LEFT JOIN appointment ZeroAppoint
INNER JOIN (
SELECT
max(a.appointmentid) appointmentid ,
a.EmpID
FROM
appointment a
WHERE
a.Visibility =0
) maxZeroAppoint
ON ZeroAppoint.appointmentid = maxZeroAppoint.appointmentid
ON e.empID = ZeroAppoint.empID
LEFT JOIN appointment OneAppoint
ON e.empID = OneAppoint.empID
and OneAppoint.Visibility = 1

With SelectedAppointments AS
{
SELECT * FROM Appointments WHERE Visibility <> 2
}
SELECT Employee.Id, < All columns of SelectedAppointments unless EmployeeId>
FROM Employee LEFT JOIN SelectedAppointments
on Employee.Id = SelectedAppointments.EmployeeId

select *
from Employee as Emp
left outer join
(select top 1 *
from Appointments
where Visibility <> 2
order by Visibility desc) as App
on Emp.EmpID = App.EmpID

Related

How to get count of registered sets combination and non registered sets as '0' value

I had 2 individual tables named manager, employee.
In the manager table we have ID, a list of managers, in the employee table we have ID, a list of employees, and another column named manager_id as a foreign key. Total 20 combinations
Now there is another table called registration which has manager and employee as separate columns along with other columns. I want a select query of All 20 manager and employee combinations for which non registered combinations should appear as '0'.
I tried with below query but not getting expected output
Query:
select r.manager,r.employee,count(*)
from registration r
group by r.manager,r.employee
union all
select s.manager, i.employee,null
from manager m, employee e
where m.id = e.manager_id
---> It is showing output in a way where the registration table list is coming first with count and later with all 20 combinations as null value in count column
I don't know the exact column names of the registration table, but the query should be something like this:
select
e.id,
e.manager_id,
(case r.employee_id is null then 0 else 1 end) as is_registered
from
employee e
left join registration r
on r.employee_id = e_id and r.manager_id = e.manager_id
This is the query I modified
select m.manager, e.employee,
sum(case when r.employee is null then 0 else 1 end) as total
from employee e
left join registration r on r.employee = e.employee
left join manager m on m.id = e.manager_id
group by m.manager, e.employee, r.employee

SELECT and JOIN to return only one row for each employee

I have a user table that stores the employeeId, lastName, firstName, department, hire date and mostRecentLogin.
I have another table that stores the employeeId, emailAddress.
The emailAddress table can have multiple rows for an employee if they have multiple email addresses.
I'm trying to return results that only show one row for each employee. I don't care which email address, just as long as it only picks one.
But all the queries I've tried always return all possible rows.
Here is my most recent attempt:
select *
from EmployeeInfo i
left join EmployeeEmail e ON i.employeeId = e.employeeId
where i.hireDate = 2015
and employeeId IN (
SELECT MIN(employeeId)
FROM EmployeeInfo
GROUP BY employeeId
)
But then again, this returns all possible rows.
Is there a way to get this to work?
Use a sub-query instead of a join:
select *
, (select top 1 E.EmailAddress from EmplyeeEmail E where E.employeeId = I.employeeId)
from EmployeeInfo I
where I.hireDate = 2015;
Note: If you change your mind and decide you do have a preference as to which email address is returned then just add an order by to the sub-query - otherwise it is truly unknown which one you will get.
This should work.
SELECT *
FROM EmployeeInfo
Left JOIN EmployeeEmail
ON EmployeeInfo.employeeId = EmployeeEmail.employeeId
WHERE EmployeeInfo.hireDate = '2015'
GROUP BY EmployeeInfo.employeeId;

How do i include data from a joined table that doesnt meet the WHERE condition as a null value(SQL)

I have 2 tables employees and Medical leave, which are related by the Employee ID, and basically the Medical leave table will have multiple data of a single employee who takes multiple leaves, I want to filter out the data by the month of the medical leave, and include the employees whose medical leave doesnt occur on the filtered month as a null value.
EMPLOYEES MEDICAL
|employee|ID| |ID|DateOfLeave|
A 1 1 2019/1/3
B 2 1 2019/4/15
C 3 2 2019/5/16
D 4
The sql statement i came up with filters the specific month of the leave and counts the number of times they took a leave on that month such as January, it also includes employees who doesnt have any leave as a '0', however the employees who have medical leaves which doesnt occur on January doesnt show up in the result set at all, how can i show them to have 0 medical leaves in the month of january?
select employees.employee, employees.ID,
count(medical.DateOfLeave) as NumberOfLeaves
from employees
left outer join medical on employees.ID = medical.ID
where (MONTH(DateOfLeave) = 1) or (medical.DateOfLeave is null)
group by employees.employee,employees.ID
RESULT SET
|Employee|ID|NumberOfLeaves|
A 1 1
C 3 0
D 4 0
As you can see B disappears,but i want it to show in the result set as a '0' like employee C and D
I know its because employee B's medical data doesnt meet the condition of the where clause, but how do i write a statement that includes employees who have medical leaves which doesnt occur on january in the result set as a 0??
Your query is only showing results for employees that have leave in January or do not have leave at all.
Instead, you only want to join to records in your medical table if there are records for the specified month, then you'll group your results and get the counts from there.
In order to do this, you need to change the condition for your join to include your Month filter.
Here's a working example using table variables
DECLARE #Employees TABLE (ID INT, Employee CHAR(1))
DECLARE #Medical TABLE (ID INT, DateOfLeave DATE)
INSERT INTO #Employees
VALUES (1, 'A'), (2,'B'), (3,'C'), (4, 'D')
INSERT INTO #Medical
VALUES (1, '2019-01-03'), (1, '2019-04-15'), (2, '2019-05-16')
SELECT e.employee,
e.ID,
count(m.DateOfLeave) AS NumberOfLeaves
FROM #Employees e
LEFT OUTER JOIN #Medical m ON e.ID = m.ID AND MONTH(DateOfLeave) = 1
GROUP BY e.employee,e.ID
left outer join will first join the table and then filter. in your case B is left out in the join itself so thats why the filter is not working. you can try this
select employees.employee, employees.ID,
nvl(count(medical.DateOfLeave),0) as NumberOfLeaves
from employees
left outer join (select * from medical
where (MONTH(DateOfLeave) = 1))
on employees.ID = medical.ID
group by employees.employee,employees.ID
or you can also try this
select e.id, employee, count(dateofleave)
from employee e, medical m
where e.id = m.id
and month(m.DateOfLeave) = 1
group by e.id, employee
UNION ALL
select id, employee, 0
from employee e
where not exists(select 1 from medical m
where e.id = m.id
and month(m.DateOfLeave) = 1

SQL INNER JOIN issue when value as 0

I have shortened my query & posted only relevant parts. There are many INNER JOINS. Here is the query :-
DECLARE
#startdate DATE = '2018-05-01',
#enddate DATE = '2018-05-05';
WITH calendar
AS (SELECT #startdate AS Dates
UNION ALL
SELECT Dateadd(dd, 1, Dates)
FROM calendar
WHERE Dates < #enddate)
SELECT emp.Code, cv1.CategoryName AS Category FROM (
SELECT *
FROM calendar c
CROSS JOIN (SELECT DISTINCT Id
FROM [dbo].[Employee] where CompanyId = 1) E
WHERE NOT EXISTS (SELECT 1
FROM [dbo].[ShiftSchedule] t
WHERE c.Dates = t.ShiftDate
AND E.Id = t.EmployeeId AND CompanyId = 11)) AS c
INNER JOIN [dbo].[Employee] emp
ON c.Id = emp.Id
INNER JOIN [dbo].[Category] cv1
ON cv1.id = emp.Category
AND emp.Id IN ( 400 )
OPTION (maxrecursion 0)
The problem here is in the INNER JOIN of [dbo].[Category].
In very rare cases - Category is found 0 in Employee Table. So what I want is if Category is 0 then also that record should be included in Result Set. Currently it skips the Records with 0.
Can this be achieved in the above query?
Example :- In Employee table I have an employee Steve & in Category
Column Value is 0. And in Category Table in column Id, there is no
record with 0. So this Employee Steve is not coming in result set.
Basically, you're simply asking for your employee to be returned even when it cannot be matched to a category. That's easy: that's what a LEFT JOIN is for. There's no reason to treat 0 as special here: based on your description, it seems to me as if you'd want the same for any other values that don't exist as category IDs, it's just that there are no such other values.

SQL - Select highest value when data across 3 tables

I have 3 tables:
Person (with a column PersonKey)
Telephone (with columns Tel_NumberKey, Tel_Number, Tel_NumberType e.g. 1=home, 2=mobile)
xref_Person+Telephone (columns PersonKey, Tel_NumberKey, CreatedDate, ModifiedDate)
I'm looking to get the most recent (e.g. the highest Tel_NumberKey) from the xref_Person+Telephone for each Person and use that Tel_NumberKey to get the actual Tel_Number from the Telephone table.
The problem I am having is that I keep getting duplicates for the same Tel_NumberKey. I also need to be sure I get both the home and mobile from the Telephone table, which I've been looking to do via 2 individual joins for each Tel_NumberType - again getting duplicates.
Been trying the following but to no avail:
-- For HOME
SELECT
p.PersonKey, pn.Phone_Number, pn.Tel_NumberKey
FROM
Persons AS p
INNER JOIN
xref_Person+Telephone AS x ON p.PersonKey = x.PersonKey
INNER JOIN
Telephone AS pn ON x.Tel_NumberKey = pn.Tel_NumberKey
WHERE
pn.Tel_NumberType = 1 -- e.g. Home phone number
AND pn.Tel_NumberKey = (SELECT MAX(pn1.Tel_NumberKey) AS Tel_NumberKey
FROM Person AS p1
INNER JOIN xref_Person+Telephone AS x1 ON p1.PersonKey = x1.PersonKey
INNER JOIN Telephone AS pn1 ON x1.Tel_NumberKey = pn1.Tel_NumberKey
WHERE pn1.Tel_NumberType = 1
AND p1.PersonKey = p.PersonKey
AND pn1.Tel_Number = pn.Tel_Number)
ORDER BY
p.PersonKey
And have been looking over the following links but again keep getting duplicates.
SQL select max(date) and corresponding value
How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?
SQL Server: SELECT only the rows with MAX(DATE)
Am sure this must be possible but been at this a couple of days and can't believe its that difficult to get the most recent / highest value when referencing 3 tables. Any help greatly appreciated.
select *
from
( SELECT p.PersonKey, pn.Phone_Number, pn.Tel_NumberKey
, row_number() over (partition by p.PersonKey, pn.Phone_Number order by pn.Tel_NumberKey desc) rn
FROM
Persons AS p
INNER JOIN
xref_Person+Telephone AS x ON p.PersonKey = x.PersonKey
INNER JOIN
Telephone AS pn ON x.Tel_NumberKey = pn.Tel_NumberKey
WHERE
pn.Tel_NumberType = 1
) tt
where tt.rn = 1
ORDER BY
tt.PersonKey
you have to use max() function and then you have to order by rownum in descending order like.
select f.empno
from(select max(empno) empno from emp e
group by rownum)f
order by rownum desc
It will give you all employees having highest employee number to lowest employee number. Now implement it with your case then let me know.