How do i connect both these tables to have data connected based on department names and week number. So that if the weeknumber don't match up, it shows nulls for others.
http://sqlfiddle.com/#!6/3bbd3/1
A full outer join should do the trick:
SELECT d.id,
d.name,
f.id,
DATEPART(WEEK, setupdate) as WeekNumber
FROM departments d
FULL OUTER JOIN forecast f ON d.name = f.name AND
DATEPART(WEEK, setupdate) = DATEPART(WEEK, forecast)
Related
How can I get the absence days and the present days of all employees , I would like an output like this:
employeeId DATE Status
1 2021/03/04 Absent
1 2021/03/05 Present
2 2021/03/04 Present
2 2021/03/05 Present
What I can get now only the present days :
select distinct DATEPART(dw,er.AddAt) as dayId,
DATENAME(dw,er.AddAt) as dayname,
DATEPART(DAY,er.AddAt) as monthday,
er.employeeId,firstName as Name
from records er,employee
where er.employeeId=employee.employeeId
Update:
After Testing the solution of #Gordon Linoff , that's what I got:
and I have two problems :
I have duplicate data ( 3 times duplicate )
When I select a other month than February , I got no data.
select Day, WeekdayName, e.employeeid,
(case when r.employeeid is not null then 'present' else 'absent' end)
from Get_Calendar_Date(DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0) ,DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1)) c cross join
employee e left join
records r
on c.Day = DATEPART(DAY,r.AddAt) and e.employeeid = r.employeeid
where Month=1
Let me assume that you have a calendar table and a table of all employees. The idea is then to do a cross join to generate the rows and a left join to bring in the existing data:
select c.dayid, c.dayname, e.employeeid,
(case when r.employeeid is not null then 'present' else 'absent' end)
from calendar c cross join
employees e left join
records r
on c.dayid = r.dayid and e.employeeid = r.employeeid;
I assume you have a calendar table because you have a column called dayid. If you don't have one, you can construct one using a numbers table, a recursive CTE, a subquery on records or some other method.
You can probably just use existing dates for the calendar:
from (select distinct dayid from records) d
I have a table of Visits on the Hospital, included DoctorID, PacientID, Date....
I did like this but I recieved an error.
SELECT
d.DoctorID, COUNT(v.DoctorID)
FROM Visits v
left join Doctors d on v.DoctorID=d.DoctorID
You care missing the group by:
SELECT d.DoctorID, COUNT(v.DoctorID)
FROM Doctors d LEFT JOIN
Visits v
ON v.DoctorID = d.DoctorID
GROUP BY d.DoctorID;
In addition, you presumably want the LEFT JOIN starting with Doctors so you keep all doctors.
Your query is missing a GROUP BY clause. Also I do not see the need for a JOIN. If you want the count of (distinct) patientsIDs per doctorID, you can get that information directly from the visit table, like so:
select doctorID, count(distinct patientID) from visits group by doctorID
Or, if you also want to see doctors that have no patients:
select d.doctorID, count(distinct v.patientID)
from doctors d
left join visits v on v.doctorID = d.doctorID
group by d.doctorID
Live demo on db<>fiddle
You are missing GroupBy clause.
So you can fix it in this way
SELECT d.Name, COUNT(v.DoctorID) AS PantientCount
FROM Doctors d
LEFT JOIN Visits v ON d.DoctorId = v.DoctorId
GROUP BY d.Name
You can also using Conditional aggregation query with a group by like below.
SELECT d.Name, SUM(CASE WHEN v.CustomerId IS NOT NULL THEN 1 ELSE 0 END) AS PantientCount
FROM Doctors d
LEFT JOIN Visits v ON d.DoctorId = v.DoctorId
GROUP BY d.Name
Output
I have two tables, employee and employee time entry. I have run a query that is showing me all employees with the sum of time entered or 0 as null value. In the next column I have week number. If employee has not entered time during the week than it is giving me 0 but it is also giving me null value at the week number. how can I force query to show me week number, assuming no entry was made by employee.
Select
Concat(Empfname,Emplname) as EmployeeName,
department,
iif (sum(whours) is null, 0, sum(whours)) CurrentHours,
Datepart (ww,wdate) WeekNum
From
employee as e
left outer join
TimeEntry as w on e.id = w.eId
and wdate between '01/01/2017' and '01/31/2017'
group by
Concat(Empfname,Emplname), department, Datepart(ww, wdate)
Output
EmployeeName Department CurrentHours WeekNum
------------------------------------------------
John Smith Sales 8 1
Smith John Operations 0 Null
How can I tell it is also from WeekNum 1?
Thanks
The idea is to generate all rows using cross join and then use left join to bring in the rows you want something like this:
Select Concat(e.Empfname, e.Emplname) as EmployeeName, e.department,
coalesce(sum(whours), 0) as CurrentHours
datepart(week, wd.wdate) as WeekNum
from employee e cross join
(select distinct wdate from TimeEntry) wd left outer join
TimeEntry tw
on e.id = w.eId and tw.wdate = wd.wdate
where wd.wdate between '2017-01-01' and '2017-01-31'
group by Concat(e.Empfname, e.Emplname), e.department, Datepart(week, wd.wdate);
Try this:
Select Concat(Empfname,Emplname) as EmployeeName, department
iif (sum(whours) is null, 0, sum(whours)) CurrentHours
ISNULL(Datepart (ww,wdate),1) WeekNum
From employee as e left outer join TimeEntry as w on e.id=w.eId
and wdate between '01/01/2017' and '01/31/2017'
group by Concat(Empfname,Emplname), department, ISNULL(Datepart (ww,wdate),1)
which will force any NULL value to show 1 instead of NULL itself
Ok so I need to write a query that I am probably making much more complicated than it needs to be but I could use some help.
I need to select records of clients that have not been seen for a year or longer, have seen us more than once but can be only once if it is not at certain locations.
So what I have so far is:
WITH CTE AS
(
SELECT
client_id,
location_id,
employee_id,
create_timestamp,
ROW_NUMBER() OVER(PARTITION BY person_id ORDER BY create_timestamp DESC) AS ROW
FROM
client_Appointment
)
SELECT
c.client_id,
COUNT(*)
FROM
CTE AS ce
INNER JOIN person AS c
ON p.person_id= ce.client_id
INNER JOIN employee_mstr AS em
ON em.employee_id = ce.empoyee_id
INNER JOIN location_mstr AS lm
ON lm.location_id = ce.location_id
WHERE
ce.create_timestamp <= CONVERT(VARCHAR(10), DATEADD(Year,-1,GETDATE()), 120)
GROUP BY
p.person_id
HAVING
COUNT(*) > 1
I'm unsure where to go from here. Also this does not get me all the info I need and if I add that information to the select clause I have to use it in group by which means I don't get all the needed records.
Thanks
So you want only clients who have not been seen in a year or more,
then clients that have either one visit NOT at certain locations OR more than one visit. Did I get that right?
Note: Just replace (VALUES(1),(2),(3)) with your table name
WITH CTE_visits
AS
(
SELECT
c.client_id,
COUNT(*) AS total_visits,
SUM(
CASE
WHEN ce.location_id IN (SELECT ID FROM (VALUES(1),(2),(3)) AS A(ID)) THEN 0 --so when it is a certain location then do NOT count it
ELSE 1 --if it is not at the certain locations, then count it
END
) AS visits_not_at_certain_locations
FROM
client_Appointment AS ce
INNER JOIN person AS c
ON p.person_id= ce.client_id
INNER JOIN employee_mstr AS em
ON em.employee_id = ce.empoyee_id
INNER JOIN location_mstr AS lm
ON lm.location_id = ce.location_id
CROSS APPLY(SELECT client_id, MAX(create_timestamp) last_visit FROM client_Appointment WHERE client_id = ce.client_id GROUP BY client_id) CA --find most recent visit for each client_id
WHERE
ce.create_timestamp <= CONVERT(VARCHAR(10), DATEADD(Year,-1,GETDATE()), 120) --remember this only counts visits over a year ago
AND last_visit <= CONVERT(VARCHAR(10), DATEADD(Year,-1,GETDATE()), 120) --says only return client_id's who's last visit is more than a year ago
GROUP BY
p.person_id
)
SELECT *
FROM CTE_visits
WHERE visits_not_at_certain_locations = 1 --seen once NOT at certain locations
OR total_visits > 1 --seen more than once at any location
Well I have this -
Table DimDate- Date
Table Employee- Id,Name,Points,Date
Now the Employee table has points for everyday unless they did not come...so the Date does not have all the Dates entries... I mean for e.g in a week he did not come for 2 days the Employee table has only 5 rows...so I have this dimdate table which has all the dates till 2050 which I want to join with and add Zeros for the dates he does not have points. So I have written this query but does not work -
Select E.EmployeeId,D.Date,isNull(E.Points,0) from DimDate D left join Employee E on D.Date between '01-01-2009'and '06-01-2009' where E.EmployeeId=1
The above query give multiple dates and I tried group by on Date but does not work.
You probably dont want to join the two tables on a date range but a date. Then filter the record set by the date range. example
Select
E.EmployeeId,
D.Date,
isNull(E.Points,0)
from DimDate D
left join Employee E on D.Date = E.Date
where E.EmployeeId=1
AND D.Date Between '01-01-2009'and '06-01-2009'
Edited:
Select
E.EmployeeId,
D.Date,
isNull(E.Points,0)
from DimDate D
left join Employee E on D.Date = E.Date And E.EmployeeId=1
where D.Date Between '01-01-2009'and '06-01-2009'
OR
Select
E.EmployeeId,
D.Date,
isNull(E.Points,0)
from DimDate D
left join Employee E on D.Date = E.Date
where (E.EmployeeId = 1 OR E.EmployeeId is NULL)
AND D.Date Between '01-01-2009'and '06-01-2009'
I think you need a cross join between the dimdates table and the table where your employees are defined. This will give you a list of records with all employee/date combinations. Then the result of that needs to be left outer joined to the table that has the employee points records.
Something like:
Select CJ.EmployeeId,CJ.Date,isNull(E.Points,0)
from (SELECT EmployeeID, D.Date
from DimDate D CROSS JOIN [EmployeeDefinitionTable] as edt) as CJ
left outer join Employee E on CJ.Date =E.Date AND CJ.EmployeeId = E.EmployeeId
where CJ.Date between '01-01-2009'and '06-01-2009'
and E.EmployeeId = 1
Where EmployeeDefinitionTable is a table that uniquely lists all employees (or at least their id's for this problem statement).
This also captures employees with no points entries.
The between statement and/or EmployeeId filtering could be moved up into the cross join if it fits your requirements. It would make the cross join more efficient.