Click here to Skip to main content
15,891,409 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have a table on SQL Server that looks like this:

MEMBER_ID   ,  STATUS   ,  DATE
1   ,  A   ,  1/1/2012
1   ,  B   ,  9/1/2012
1   ,  A   ,  10/1/2012
2   ,  A   ,  1/1/2012
2   ,  C   ,  3/1/2012
2   ,  A   ,  13/1/2012


Each member only has ONE status recorded per day, it is only recorded when it changes.

I need to be able to determine the Members with any given status
(eg 'A') on a particular day. (remember that I don't have a status record for each day, just the days when it has changed)

Can I query the table directly? Should I create a view something like this:
MEMBER_ID   ,  STATUS   ,  START DATE   ,  END DATE   , 
1   ,  A   ,  1/1/2012   ,  9/1/2012
1   ,  B   ,  9/1/2012   ,  10/1/2012
1   ,  A   ,  10/1/2012   ,  31/12/2999 (or blank)
2   ,  A   ,  1/1/2012   ,  3/1/2999
2   ,  C   ,  3/1/2012   ,  13/1/2999
2   ,  A   ,  13/1/2012   ,  31/12/2999 (or Blank)

How do I transform the data from first format into the second above? (using just a query or stored procedure)

Help much appreciated.
Posted
Comments
Maciej Los 16-May-12 11:37am    
To answer this question we need to know the relations between fields. Based on what codition do we know which date is starting date and which is ending date? Is this a [Status] {A, B, C}?

If I understood the question correctly then I think one record per each member has to be picked up whose satus is as specified and the date is either less than or equal to the entered date. If it is so then I think the following query can be used.
SQL
SELECT MEMBER_ID, MAX(STATUS), MAX([DATE]) FROM MEMBERSTATUS
WHERE [DATE] <= '2012/01/10' AND STATUS = 'A'
GROUP BY MEMBER_ID
--Output for the given data
--1	A	2012-01-10
--2	A	2012-01-01

This query groups the records by MEMBER_ID where the Date is less than or equal to the given date then it picks up the record corresponding the maximum date.
 
Share this answer
 
Comments
Maciej Los 16-May-12 11:39am    
VJ, please see my comment to the question [edit] and answer [/edit] ;)
To get data in the second format, based on one table and one column we need to write scalar-valued function[^]:
SQL
USE [DATABASE1]
GO
/****** Object:  UserDefinedFunction [dbo].[GetNextStatusDate]    Script Date: 05/17/2012 16:21:30 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[GetNextStatusDate] 
(
	-- parameters:
	@MemID INT,
	@cDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
	-- Declare the return variable here
	DECLARE @Result DATETIME

	-- Add the T-SQL statements to compute the return value here
	SELECT @Result = MIN([DATE])
	FROM [DATABASE1].[dbo].[TABLE1]
	WHERE [MEMBER_ID] = @MemID AND [DATE] > @cDate

	SET @RESULT = ISNULL(@RESULT,'2099-12-31')
		
	-- Return the result of the function
	RETURN @Result

END

Than, query like this:
SQL
SELECT [MEMBER_ID], [STATUS], [DATE] AS [START_DATE], [DATABASE1].[dbo].[GetNextStatusDate] ([MEMBER_ID], [DATE]) AS [END_DATE]
FROM    [DATABASE1].[dbo].[MemberWork]

Results:

MEMBER_IDSTATUSSTART_DATEEND_DATE
1A2012-01-012012-01-09
1B2012-01-092012-01-10
1A2012-01-102099-12-31
2A2012-01-012012-01-03
2C2012-01-032012-01-13
2A2012-01-132099-12-31

If you woukd like to change the final format of date, use different parameter for CONVERT[^] function.
 
Share this answer
 
v3
Comments
VJ Reddy 16-May-12 13:13pm    
I have seen your comment. From the information given in the question it can be interpreted as:
on 1/1/12 Member 1 Status is A, which changes to B on 9/1/12 and then changes to A on 10/1/12.
Similarly on 1/1/12 Member 2 Status is A, which changes to C on 3/1/12 and then changes to A on 13/1/12.
Now the requirement is to find all members with a particular status on any given day. Say we want on 10/1/12 with status A.
So, member 1 with status A is from 10/1/12 on wards hence can be included, then member 2 with status A is from 3/1/12 to 12/1/12, and 10/1/12 falls in this range and can be included in the result.

OP stated in the question whether it is required to create a view with start date and end date to retrieve the above result or whether the above result can be directly taken from table. I think the above data can be retrieved directly from the initial table as shown in my solution.

Thank you :)
Maciej Los 16-May-12 16:32pm    
I agree with you, VJ. The presentation of data in a distination format depend of user preferences.
You gave me a light on OP question... Thank you.
Now i see an error in my answer. My query returns only 4 records...

The problem is still unresolved. solved!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900