Reputation: 2611
I have a scenario where I need to compare the list of a values for a particular day with the previous day for same person. And for every day I need to maintain a difference of those two consecutive days.
This is data of sales people, every day they visit few houses from the whole list of houses in their town.
Below is the data I have:
Houses:
Select Distinct House_id from tbl_houses;
Visits:
Select sales_person_id, Date, visited_house_id;
Now, I have two different tables like this:
House_id
1
2
3
4
5
And, the sales persons visit's data is as follows:
sales_person_id Date visited_house
1 12/6/16 1
1 12/6/16 2
2 12/6/16 1
2 13/6/16 3
3 12/6/16 3
1 13/6/16 1
1 13/6/16 3
A sales person can visit a already visited house and more than one sales person can visit the same house on same day. No restrictions on this.
And, the desired output as follows:
Sales_person_Id Date Visited_Houses Not_Visited_Houses
1 12/6/16 [1,2] [3,4,5]
1 13/6/16 [1,2,3] [4,5]
2 12/6/16 [1] [2,3,4,5]
2 13/6/16 [1,3] [2,4,5]
3 12/6/16 [3] [1,2,4,5]
How can we achieve this in sql?
Upvotes: 0
Views: 115
Reputation: 50173
Please check below small piece of code which could help you :
SELECT DISTINCT
H.sales_person_id,
H.Date,
Visited_Houses = STUFF(
(
SELECT ','+CONVERT(NVARCHAR(MAX), houseid)
FROM history
WHERE [sales_person_id] = H.sales_person_id
AND [Date] = H.Date FOR XML PATH('')
), 1, 1, '[')+']',
Not_Visited_Houses = STUFF(
(
SELECT ','+CONVERT(NVARCHAR(MAX), TT.House_id)
FROM
(
SELECT HS1.House_id,
H1.sales_person_id
FROM house HS1
LEFT JOIN #history H1 ON H1.houseid = HS1.House_id
AND H1.sales_person_id = H.sales_person_id AND H1.Date = H.Date
) TT
WHERE TT.sales_person_id IS NULL FOR XML PATH('')
), 1, 1, '[')+']'
FROM house HS
INNER JOIN #history H ON H.houseid = HS.House_id;
Desired Output :
sales_person_id Date Visited_Houses Not_Visited_Houses
--------------- ---------- ---------------- -------------------
1 2016-06-12 [1,2] [3,4,5]
1 2016-06-13 [1,3] [2,4,5]
2 2016-06-12 [1] [2,3,4,5]
2 2016-06-13 [3] [1,2,4,5]
3 2016-06-12 [3] [1,2,4,5]
Note : The above output is as per your Data that you have given.
Hope, it will help you.
Upvotes: 1
Reputation: 5208
For SQL Server (you can alter the CTE at the top to use whatever date range you like):
WITH cteDates
AS
(
SELECT CAST(GETDATE() AS date) DT
UNION
SELECT CAST(GETDATE() - 1 AS date)
)
SELECT
SP.sales_person_id
, D.[DT] [Date]
, '[' + LEFT(V.Visited, LEN(V.Visited) - 1) + ']' Visited
, '[' + LEFT(NV.NotVisited, LEN(NV.NotVisited) - 1) + ']' Visited
FROM
cteDates D
CROSS JOIN (SELECT DISTINCT sales_person_id FROM tbl_visits) SP
OUTER APPLY
(
SELECT
CAST(
(
SELECT CAST(visited_house_id AS varchar) + ','
FROM tbl_visits
WHERE
sales_person_id = SP.sales_person_id
AND [Date] = D.DT
ORDER BY visited_house_id
FOR XML PATH ('')
)
AS varchar) Visited
) V
OUTER APPLY
(
SELECT
CAST(
(
SELECT CAST(House_id AS varchar) + ','
FROM tbl_houses
WHERE House_id NOT IN
(
SELECT visited_house_id
FROM tbl_visits
WHERE
sales_person_id = SP.sales_person_id
AND [Date] = D.DT
)
ORDER BY House_id
FOR XML PATH ('')
)
AS varchar) NotVisited
) NV
ORDER BY
sales_person_id
, [Date]
Upvotes: 1