|
|
|
SSC Journeyman
      
Group: General Forum Members
Last Login: Friday, May 10, 2013 2:47 PM
Points: 83,
Visits: 244
|
|
Hello Everyone
I Have one task, in that there are two tables, one has student testing dates and other has student enrollment dates.
CREATE TABLE #TestDates ( iSchoolYearCode int NOT NULL, dtStartDate DATETIME NOT NULL )
insert into #TestDates values (2011,'2011-08-22 00:00:00.000') insert into #TestDates values (2011,'2011-12-14 00:00:00.000') insert into #TestDates values (2011,'2012-05-01 00:00:00.000') insert into #TestDates values (2012,'2012-08-30 00:00:00.000')
This tables has students Test Dates.
CREATE TABLE #EnrollmentDates ( iSchoolYearCode int NOT NULL, dtRunDate DATETIME NOT NULL )
insert into #EnrollmentDates values (2011,'2011-06-16 06:00:06.780') insert into #EnrollmentDates values (2011,'2011-10-14 11:43:48.840') insert into #EnrollmentDates values (2011,'2011-11-01 06:00:05.353') insert into #EnrollmentDates values (2011,'2011-12-03 06:00:06.980') insert into #EnrollmentDates values (2011,'2012-01-11 06:00:06.947') insert into #EnrollmentDates values (2011,'2012-01-28 06:00:06.733') insert into #EnrollmentDates values (2011,'2012-02-11 06:00:07.130') insert into #EnrollmentDates values (2011,'2012-03-10 06:00:09.083') insert into #EnrollmentDates values (2011,'2012-04-14 06:00:08.330') insert into #EnrollmentDates values (2011,'2012-05-12 06:00:11.163') insert into #EnrollmentDates values (2011,'2012-06-14 06:00:07.893') insert into #EnrollmentDates values (2012,'2012-10-08 23:47:43.897')
This tables has students Enrollment Dates.
I need to display most nearest Enrollment Dates with respect to Test dates
something link this
dtStartDate dtRunDate 2011-08-22 00:00:00.000 2011-06-16 06:00:06.780 2011-12-14 00:00:00.000 2011-12-03 06:00:06.980 2012-05-01 00:00:00.000 2012-04-14 06:00:08.330 2012-08-30 00:00:00.000 2012-06-14 06:00:07.893
Please help me to build the logic for this
Thanks
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Yesterday @ 2:45 PM
Points: 8,567,
Visits: 8,218
|
|
|
|
|
|
SSC Journeyman
      
Group: General Forum Members
Last Login: Friday, May 10, 2013 2:47 PM
Points: 83,
Visits: 244
|
|
Sean Lange (10/10/2012) This looks a lot like homework. We don't typically provide answers for homework because we want you to learn.
However, it seems you want the most recent date prior to the test date for each value in the test table?
This is not Homework. I have task in that i need to use this logic.
and You correct I need most recent date prior to the test date.
I am thinking to do with cursor, what you say?
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Yesterday @ 2:45 PM
Points: 8,567,
Visits: 8,218
|
|
yogi123 (10/10/2012)
Sean Lange (10/10/2012) This looks a lot like homework. We don't typically provide answers for homework because we want you to learn.
However, it seems you want the most recent date prior to the test date for each value in the test table?This is not Homework. I have task in that i need to use this logic. and You correct I need most recent date prior to the test date. I am thinking to do with cursor, what you say?
No you certainly don't need a cursor for this. Cursors are very rarely required for data manipulation. They are very resource intensive and can be huge issue for performance.
I can think of two ways to do this immediately without a cursor. I am sure there are other ways to do this.
The first is an inline subquery.
select *, (select top 1 dtRunDate from #EnrollmentDates where dtRunDate <= #TestDates.dtStartDate order by dtRunDate desc) as dtRunDate from #TestDates
The second uses Apply as a correlated subquery.
select * from #TestDates outer apply (select top 1 dtRunDate from #EnrollmentDates where dtRunDate <= #TestDates.dtStartDate order by dtRunDate desc) x
The second approach will produce a slightly simpler execution plan. You need to make sure you understand the logic of either approach.
BTW, excellent job posting ddl and sample data. I wish more people would post things so nicely. It really makes it easy for us to help.
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Moden's splitter.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs
|
|
|
|
|
SSC Journeyman
      
Group: General Forum Members
Last Login: Friday, May 10, 2013 2:47 PM
Points: 83,
Visits: 244
|
|
Sean Lange (10/10/2012)
yogi123 (10/10/2012)
Sean Lange (10/10/2012) This looks a lot like homework. We don't typically provide answers for homework because we want you to learn.
However, it seems you want the most recent date prior to the test date for each value in the test table?This is not Homework. I have task in that i need to use this logic. and You correct I need most recent date prior to the test date. I am thinking to do with cursor, what you say? No you certainly don't need a cursor for this. Cursors are very rarely required for data manipulation. They are very resource intensive and can be huge issue for performance. I can think of two ways to do this immediately without a cursor. I am sure there are other ways to do this. The first is an inline subquery. select *, (select top 1 dtRunDate from #EnrollmentDates where dtRunDate <= #TestDates.dtStartDate order by dtRunDate desc) as dtRunDate from #TestDates
The second uses Apply as a correlated subquery. select * from #TestDates outer apply (select top 1 dtRunDate from #EnrollmentDates where dtRunDate <= #TestDates.dtStartDate order by dtRunDate desc) x
The second approach will produce a slightly simpler execution plan. You need to make sure you understand the logic of either approach. BTW, excellent job posting ddl and sample data. I wish more people would post things so nicely. It really makes it easy for us to help. 
Thank You so much
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Tuesday, May 14, 2013 9:06 AM
Points: 223,
Visits: 1,137
|
|
yogi123 (10/10/2012)
Hello Everyone I Have one task, in that there are two tables, one has student testing dates and other has student enrollment dates. CREATE TABLE #TestDates ( iSchoolYearCode int NOT NULL, dtStartDate DATETIME NOT NULL )
insert into #TestDates values (2011,'2011-08-22 00:00:00.000') insert into #TestDates values (2011,'2011-12-14 00:00:00.000') insert into #TestDates values (2011,'2012-05-01 00:00:00.000') insert into #TestDates values (2012,'2012-08-30 00:00:00.000')
This tables has students Test Dates. CREATE TABLE #EnrollmentDates ( iSchoolYearCode int NOT NULL, dtRunDate DATETIME NOT NULL )
insert into #EnrollmentDates values (2011,'2011-06-16 06:00:06.780') insert into #EnrollmentDates values (2011,'2011-10-14 11:43:48.840') insert into #EnrollmentDates values (2011,'2011-11-01 06:00:05.353') insert into #EnrollmentDates values (2011,'2011-12-03 06:00:06.980') insert into #EnrollmentDates values (2011,'2012-01-11 06:00:06.947') insert into #EnrollmentDates values (2011,'2012-01-28 06:00:06.733') insert into #EnrollmentDates values (2011,'2012-02-11 06:00:07.130') insert into #EnrollmentDates values (2011,'2012-03-10 06:00:09.083') insert into #EnrollmentDates values (2011,'2012-04-14 06:00:08.330') insert into #EnrollmentDates values (2011,'2012-05-12 06:00:11.163') insert into #EnrollmentDates values (2011,'2012-06-14 06:00:07.893') insert into #EnrollmentDates values (2012,'2012-10-08 23:47:43.897')
This tables has students Enrollment Dates. I need to display most nearest Enrollment Dates with respect to Test dates something link this dtStartDate dtRunDate 2011-08-22 00:00:00.000 2011-06-16 06:00:06.780 2011-12-14 00:00:00.000 2011-12-03 06:00:06.980 2012-05-01 00:00:00.000 2012-04-14 06:00:08.330 2012-08-30 00:00:00.000 2012-06-14 06:00:07.893
Please help me to build the logic for this Thanks
This is what I came up with...
WITH dt AS ( SELECT DENSE_RANK() OVER (ORDER BY tdt.dtStartDate) x, tdt.dtStartDate, edt.dtRunDate FROM #TestDates tdt CROSS JOIN #EnrollmentDates edt WHERE tdt.dtStartDate > edt.dtRunDate ), maxSDt AS ( SELECT DISTINCT x, MAX(dtStartDate) OVER (PARTITION BY x) y FROM dt ), maxRDt AS ( SELECT DISTINCT x, MAX(dtRunDate) OVER (PARTITION BY x) y FROM dt ) SELECT SDt.y dtStartDate, RDt.y dtRunDate FROM maxRDt RDt JOIN maxSDt SDt ON Rdt.x = SDt.x It should still be optimized but this should do.
Update... what Sean Lange posted is much better and will produce a much simpler query plan. I had not seen his last post when I posted this. Both of our approaches are better than a cursor or loop.
-- AJB xmlsqlninja.com
|
|
|
|
|
Ten Centuries
      
Group: General Forum Members
Last Login: Yesterday @ 10:37 PM
Points: 1,172,
Visits: 1,247
|
|
|
|
|
|
SSC Journeyman
      
Group: General Forum Members
Last Login: Friday, May 10, 2013 2:47 PM
Points: 83,
Visits: 244
|
|
Hi Sean
There is slight difference in requirement
so the table and data as follows
CREATE TABLE #TestDates ( iSchoolYearCode int NOT NULL, dtStartDate DATETIME NOT NULL )
insert into #TestDates values (2011,'2011-08-22 00:00:00.000') insert into #TestDates values (2011,'2011-12-14 00:00:00.000') insert into #TestDates values (2011,'2012-05-01 00:00:00.000') insert into #TestDates values (2012,'2012-08-30 00:00:00.000')
CREATE TABLE #EnrollmentDates ( iSchoolYearCode int NOT NULL, dtRunDate DATETIME NOT NULL )
insert into #EnrollmentDates values (2010,'2011-06-16 06:00:06.780') insert into #EnrollmentDates values (2011,'2011-10-14 11:43:48.840') insert into #EnrollmentDates values (2011,'2011-11-01 06:00:05.353') insert into #EnrollmentDates values (2011,'2011-12-03 06:00:06.980') insert into #EnrollmentDates values (2011,'2012-01-11 06:00:06.947') insert into #EnrollmentDates values (2011,'2012-01-28 06:00:06.733') insert into #EnrollmentDates values (2011,'2012-02-11 06:00:07.130') insert into #EnrollmentDates values (2011,'2012-03-10 06:00:09.083') insert into #EnrollmentDates values (2011,'2012-04-14 06:00:08.330') insert into #EnrollmentDates values (2011,'2012-05-12 06:00:11.163') insert into #EnrollmentDates values (2011,'2012-06-14 06:00:07.893') insert into #EnrollmentDates values (2012,'2012-10-08 23:47:43.897')
now, if the TestDate is first date of Year, then need to update first enroll date from #EnrollmentDates
so now desired output looks like
dtStartDate dtRunDate 2011-08-22 00:00:00.000 2011-10-14 11:43:48.840 2011-12-14 00:00:00.000 2011-12-03 06:00:06.980 2012-05-01 00:00:00.000 2012-04-14 06:00:08.330 2012-08-30 00:00:00.000 2012-10-08 23:47:43.897
That means we need to display first Enrollment date for first test date for particular Year.
Please help me one more time to build this.
|
|
|
|
|
SSCrazy Eights
        
Group: General Forum Members
Last Login: Yesterday @ 2:45 PM
Points: 8,567,
Visits: 8,218
|
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Tuesday, May 14, 2013 9:06 AM
Points: 223,
Visits: 1,137
|
|
Lokesh Vij (10/10/2012)
This query would give the best performance from all the queries posted above  SELECT dtStartDate, (SELECT Max(dtRunDate) FROM #EnrollmentDates WHERE dtRunDate <= #TestDates.dtStartDate) FROM #TestDates I am certainly not trying to compete with experts like Sean here. But just came up with my own better version 
I cleaned my original up which runs much faster but can't compete with Lokesh Vij's example above. ;WITH dt AS ( SELECT DENSE_RANK() OVER (ORDER BY tdt.dtStartDate) x, tdt.dtStartDate, edt.dtRunDate FROM #TestDates tdt JOIN #EnrollmentDates edt ON tdt.dtStartDate > edt.dtRunDate ), maxSDt AS ( SELECT DISTINCT x, MAX(dtStartDate) OVER (PARTITION BY x) dtStartDate, MAX(dtRunDate) OVER (PARTITION BY x) dtRunDate FROM dt ) SELECT dtStartDate, dtRunDate FROM maxSDt
-- AJB xmlsqlninja.com
|
|
|
|