I have two tables. One with dates and the other with gift dates and gift types. The third table displays the results that I am looking to achieve.
I want to display a column on the table with the product dates called 'Results'. The results should return:
'Not a Donor' if there is no gift date before the product date.
'Products Donor' if there is only one gift type Product before the Date.
'Multiple Products Donor' if there are multiple Product gift types before the Date (but there cant be an 'Other' Gift Type).
'Other Donor' if there is an 'Other' Gift type, regardless of how many products came before.
Table 1
Donor Date
Steve 2/1/2020
Steve 3/1/2020
Steve 4/1/2020
Steve 5/1/2020
Steve 6/1/2020
Steve 7/1/2020
Steve 9/1/2020
Steve 10/1/2020
Bill 2/1/2020
Bill 3/1/2020
Bill 4/1/2020
Bill 5/1/2020
Bill 6/1/2020
Bill 7/1/2020
Bill 8/1/2020
Table 2
Donor Gift Date Gift Type
Steve 8/15/2020 Product
Steve 9/15/2020 Product
Bill 5/15/2020 Product
Bill 6/15/2020 Other
Bill 7/15/2020 Product
Expected Result
Donor Date Results
Steve 2/1/2020 Not A Donor
Steve 3/1/2020 Not A Donor
Steve 4/1/2020 Not A Donor
Steve 5/1/2020 Not A Donor
Steve 6/1/2020 Not A Donor
Steve 7/1/2020 Not A Donor
Steve 9/1/2020 Products Donor
Steve 10/1/2020 Multiple Products Donor
Bill 2/1/2020 Not A Donor
Bill 3/1/2020 Not A Donor
Bill 4/1/2020 Not A Donor
Bill 5/1/2020 Not A Donor
Bill 6/1/2020 Products Donor
Bill 7/1/2020 Other Donor
Bill 8/1/2020 Other Donor
You can use a Case statement to consider each possible output:
select T.Donor,
T.Date,
Results = Case when not exists (Select top 1 1 From table2 where Donor = T.Donor and [Gift Date] < T.[Date]) then 'Not A Donor'
when exists (Select top 1 1 From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Other') then 'Other Donor'
when (Select count(1) From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Product') = 1 then 'Products Donor'
when (Select count(1) From table2 where Donor = T.Donor and [Gift Date] < T.[Date] and [Gift Type] = 'Product') > 1 then 'Multiple Products Donor'
end
from table1 T
I don't know the name of your tables so you'll have to replace them.
Related
I have below table from which i am trying to get the correspondent manager name against the employee
TITLE EMPLOYEE_ID MANAGER_ID
President 1
Vice President Engineering 10 1
Programmer 100 10
QA Engineer 101 10
Vice President HR 20 1
Health Insurance Analyst 200 20
i used below hierarchy query to get the result
select employee_id, manager_id, title, prior report_title
from employees
start with title = 'President'
connect by
manager_id = prior employee_id
order by employee_id;
But result not returning as i expected
Expected:
EMPLOYEE_ID MANAGER_ID title report_title
10 1 Vice President Engineering President
Can anyone help on this?
If you use a recursive CTE, you can get the output you want.
with emptree as
(select employee_id, title, manager_id, null as report_title
from employees
where manager_id is null
union all
select employees.employee_id, employees.title, employees.manager_id, emptree.title
from employees
join emptree
on employees.manager_id = emptree.employee_id
)
select employee_id, manager_id, title, report_title
from emptree
order by employee_id;
EMPLOYEE_ID
MANAGER_ID
TITLE
REPORT_TITLE
1
NULL
President
10
1
Vice President Engineering
President
20
1
Vice President HR
President
100
10
Programmer
Vice President Engineering
101
10
QA Engineer
Vice President Engineering
200
20
Health Insurance Analyst
Vice President HR
Question
List the first name, last name, gender, and the number of days since the last appointment of each patient and the 23/09/2019. The code written for the question is not quite right (I do not want multiple entries for one patient). Please tell me the right code for the question.
Code source: Microsoft SQL server
Code
Go
Use MedicalPractice
Select Patient.FirstName as Patient_FName, Patient.LastName as Patient_LName,
Patient.Gender as Patient_Gender,
Datediff(day, Appointment.AppDate, '2019-09-23') as
DaysBetween_LAppointmentAnd20190923
From dbo.Patient, dbo.Appointment
Where Appointment.Patient_Ref = Patient.Patient_ID
Go
Appointment input data
AppDate Patient_Ref
2019-09-17 10000
2019-09-17 10001
2019-09-18 10000
2019-09-18 10002
Patient input data
Patient_ID FirstName LastName Gender
10000 Luke Smith male
10001 Jess Fox female
10002 Lily Bay female
Try this:
Select Patient.FirstName as Patient_FName, Patient.LastName as Patient_LName,
Patient.Gender as Patient_Gender,
Datediff(day, Appointment.AppDate, '2019-09-23') as
DaysBetween_LAppointmentAnd20190923
From dbo.Patient,
INNER JOIN (SELECT Appointment.Patient_Ref,MAX(Appointment.AppDate) OVER (PARTITION BY
Appointment.Patient_Ref ORDER BY Appointment.Patient_Ref) AS AppDateFROM
dbo.Appointment) Appointment ON Appointment.Patient_Ref = Patient.Patient_ID
Go
I'm trying to formulate a SQL query to calculate the difference in the number of people "arriving" and "departing" grouped by City and Date.
TravelerID ArrivalDate DepartureDate City
1 2015-10-01 2015-10-03 New York
2 2015-10-02 2015-10-03 New York
3 2015-10-02 2015-10-04 Chicago
4 2015-10-01 2015-10-02 Chicago
I'm hoping to get a table that looks like
NumOfTravelers Date City
1 2015-10-01 New York
1 2015-10-02 New York
-2 2015-10-03 New York
1 2015-10-01 Chicago
0 2015-10-02 Chicago
-1 2015-10-04 Chicago
A positive number for NumOfTravelers means that more people arrived in that city on that particular date. A negative number for NumOfTravelers means that more people left that city on that particular date.
In trying to break down this SQL query, I've tried
SELECT COUNT(TravelerID) as NumTravelersArrivng, ArrivalDate, City FROM TravelTable GROUP BY ArrivalDate, City;
SELECT COUNT(TravelerID) as NumTravelersDeparting, DepartureDate, City FROM TravelTable GROUP BY DepartureDate, City;
I'm trying to get "NumTravelersArriving" - "NumTravelersDeparting" into a column that represents "traveler throughput" grouped by City and Date.
I've been so stumped on this. I'm using SQL Server, and having a frustrating time using Table aliases and Column aliases.
Try this:
SELECT *
FROM (
SELECT City, ArrivalDate As Date, COUNT(TravelerID) As NumOfTravelers
FROM TravelTable
GROUP BY City, ArrivalDate
) a
FULL JOIN (
SELECT City, DepartureDate As Date, COUNT(TravelerID) * -1 As NumOfTravelers
FROM TravelTable
GROUP BY City, DepartureDate
) b ON b.City = a.City AND b.Date = a.Date
can you please assist
I have a query that shows number of teachers, the site the visited and when date they visited. This query looks at all teachers visits for the past week.
I want to split the dateattended field into columns to show daily visit for the past week. Below is how it looks.
EmployeeNumber Name HomeSite Site Attended Day Attended
TP-000322789 Samuel Mohlamnyane Teacher Port Elizabeth 2014-10-18 07:23
TP-000148774 Jean Smoothie Teacher Hennopsview 2014-10-13 08:55
TP-000148774 Jean Smoothie Teacher Hennopsview 2014-10-16 08:43
TP-000148122 Anthony Mike Teacher Tzaneen 2014-10-19 09:19
TP-000148122 Anthony Mike Teacher Tzaneen 2014-10-15 08:26
TP-000328452 Geneve Gorridon Teacher Tzaneen 2014-10-14 07:44
TP-000346529 Edmos Dube Teacher Melrose 2014-10-18 07:47
TP-000321374 Anita Rene Classen Teacher Johannesburg 2014-10-17 07:57
TP-000324511 Anthonysia White Teacher Durbanville 2014-10-15 07:53
TP-000324511 Anthonysia White Teacher Durbanville 2014-10-18 12:26
TP-000327471 Moses Mathebula Teacher Polokwane 2014-10-13 05:50
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging 2014-10-15 07:06
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-13 07:26
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-16 06:51
TP-000323384 Lerato Manyanka Teacher Bedfordview 2014-10-17 08:57
Now I want to split Day attended to show date in different columns from yesterday going down to the last seven days.
Below is the code I used to get the above result set. And how the result should look like.
EmployeeNumber Name HomeSite Site Attended Day 1 Day2 Day 3 Day 4 Day 5 Day 6 Day 7
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging 2014-10-15 07:06
TP-000323383 Lerato Manyanka Teacher Bedfordview 2014-10-17 08:57 2014-10-16 06:51 2014-10-13 07:26
SELECT mdet.MemRefNo AS 'EmployeeNumber'
, cont.FirstName + ' ' + cont.LastName AS Name
, s.Name AS 'HomeSite'
, Attend.VisitedSite AS 'Site Attended'
, Attend.Weekdays AS 'Day Attended'
FROM MemberDetail mdet
INNER JOIN MembershipHistory mhis ON mdet.CurrentMembershipID = mhis.ID32
INNER JOIN contacts cont ON cont.GUID = mdet.ContactGUID
INNER JOIN Sites s ON s.id = cont.HomeSiteID
INNER JOIN Packages pg ON pg.ID = mhis.PackageID
CROSS APPLY
(
SELECT min(a1.attenddate) AS Weekdays , a1.contactguid, a1.SiteID , s.Name as VisitedSite FROM dbo.attendance a1
INNER JOIN Sites s ON s.id = a1.Siteid
WHERE DATEDIFF(DAY,a1.attenddate,GETDATE()) <= 7
and ContactGuid = mdet.ContactGuid
AND a1.isswipesuccessful = 1
GROUP BY a1.ContactGuid, DATEPART(DW, a1.attenddate),a1.SiteID , s.Name
) Attend
WHERE pg.Description LIKE '%Teacher%'
I think this is the query you want, it uses a pivot with the results from your existing query as source through a common table expression. Ideally the code could be merged into one query, but as you didn't provide any test data from the source tables, but only the output I didn't try to rewrite it. Note that if a person visited the same site more than one time in a single day, only the latest time will be shown.
-- using original query as source
;WITH visits AS (
SELECT mdet.MemRefNo AS 'EmployeeNumber'
, cont.FirstName + ' ' + cont.LastName AS Name
, s.Name AS 'HomeSite'
, Attend.VisitedSite AS 'Site Attended'
, Attend.Weekdays AS 'Day Attended'
FROM MemberDetail mdet
INNER JOIN MembershipHistory mhis ON mdet.CurrentMembershipID = mhis.ID32
INNER JOIN contacts cont ON cont.GUID = mdet.ContactGUID
INNER JOIN Sites s ON s.id = cont.HomeSiteID
INNER JOIN Packages pg ON pg.ID = mhis.PackageID
CROSS APPLY
(
SELECT min(a1.attenddate) AS Weekdays , a1.contactguid, a1.SiteID , s.Name as VisitedSite FROM dbo.attendance a1
INNER JOIN Sites s ON s.id = a1.Siteid
WHERE DATEDIFF(DAY,a1.attenddate,GETDATE()) <= 7
and ContactGuid = mdet.ContactGuid
AND a1.isswipesuccessful = 1
GROUP BY a1.ContactGuid, DATEPART(DW, a1.attenddate),a1.SiteID , s.Name
) Attend
WHERE pg.Description LIKE '%Teacher%'
)
-- query to produce results
SELECT
EmployeeNumber,
Name,
HomeSite,
[Site Attended],
[1] AS 'Day 1',
[2] AS 'Day 2',
[3] AS 'Day 3',
[4] AS 'Day 4',
[5] AS 'Day 5',
[6] AS 'Day 6',
[7] AS 'Day 7'
FROM (
SELECT *, DATEDIFF(day, [Day Attended], GETDATE()) diff
FROM visits
WHERE [Day Attended] > (GETDATE()-7) -- adjust this to limit date range
) a
PIVOT (
MAX([Day Attended]) FOR [diff] in ([1],[2],[3],[4],[5],[6],[7])
) AS Pivoted;
It would probably be trivial to modify the existing query to get the desired results.
Sample SQL Fiddle (using the sample output data as source).
Sample results:
EmployeeNumber Name HomeSite Site Attended Day 1 Day 2 Day 3 Day 4 Day 5 Day 6 Day 7
-------------------- ---------------------------------------- -------------------- -------------------- ----------------------- ----------------------- ----------------------- ----------------------- ----------------------- ----------------------- -----------------------
TP-000148122 Anthony Mike Teacher Tzaneen NULL 2014-10-19 09:19:00.000 NULL NULL NULL 2014-10-15 08:26:00.000 NULL
TP-000148194 Nonhlanhla Ndlovu Teacher Vereeniging NULL NULL NULL NULL NULL 2014-10-15 07:06:00.000 NULL
TP-000148774 Jean Smoothie Teacher Hennopsview NULL NULL NULL NULL 2014-10-16 08:43:00.000 NULL NULL
TP-000321374 Anita Rene Classen Teacher Johannesburg NULL NULL NULL 2014-10-17 07:57:00.000 NULL NULL NULL
TP-000322789 Samuel Mohlamnyane Teacher Port Elizabeth NULL NULL 2014-10-18 07:23:00.000 NULL NULL NULL NULL
TP-000323383 Lerato Manyanka Teacher Bedfordview NULL NULL NULL 2014-10-17 08:57:00.000 2014-10-16 06:51:00.000 NULL NULL
TP-000324511 Anthonysia White Teacher Durbanville NULL NULL 2014-10-18 12:26:00.000 NULL NULL 2014-10-15 07:53:00.000 NULL
TP-000346529 Edmos Dube Teacher Melrose NULL NULL 2014-10-18 07:47:00.000 NULL NULL NULL NULL
TerritoryId, Description, ParentTerritoryId, Type
--------------------------------------------------------
1, UnitedStates, null, Territory
1, John Smith, 1, Sales Rep
2, Georgia, 1, Territory
2, Jane Doe, 2, Sales Rep
2, Ann Smith, 2, Sales Rep
How can I write the following T-SQL? Let's say I'm searching for a name like "Ann Smith".
I'd like the resultset to look like:
1, United States, null, Territory
2, Georgia, 1, Territory
2, Ann Smith, 2, Sales Rep
Basically, I want to find a sales rep or sales reps and what organization they belong to all the way up the chain.
Assuming SQL Server 2005+ so we can use a recursive CTE and assuming the TerritoryId values should really be unique:
TerritoryId Description ParentTerritoryId Type
--------------------------------------------------------
1 UnitedStates NULL Territory
2 John Smith 1 Sales Rep
3 Georgia 1 Territory
4 Jane Doe 3 Sales Rep
5 Ann Smith 3 Sales Rep
Then you can do this:
WITH cteRecursion AS (
SELECT TerritoryId, Description, ParentTerritoryId, Type, 1 AS Level
FROM YourTable
WHERE Description = 'Ann Smith'
UNION ALL
SELECT t.TerritoryId, t.Description, t.ParentTerritoryId, t.Type, c.Level + 1
FROM YourTable t
INNER JOIN cteRecursion c
ON t.TerritoryId = c.ParentTerritoryId
)
SELECT TerritoryId, Description, ParentTerritoryId, Type
FROM cteRecursion
ORDER BY Level DESC;
While it is possible to have a multilevel structure in the table ideally you would want to split your table.
one table for territory and one for sales reps.
If your sales reps can have more than one territory you would need to go to 3 tables
one for sales reps, one for territory, and a lookup table.
if you are going to do a multi level table you need each entry to have a unique id