Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase 12»»

Query Help Expand / Collapse
Author
Message
Posted Wednesday, October 10, 2012 1:20 PM
SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC 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
Post #1371090
Posted Wednesday, October 10, 2012 1:52 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Yesterday @ 2:45 PM
Points: 8,567, Visits: 8,218
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?


_______________________________________________________________

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
Post #1371101
Posted Wednesday, October 10, 2012 1:55 PM
SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC 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?
Post #1371102
Posted Wednesday, October 10, 2012 2:03 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy 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
Post #1371108
Posted Wednesday, October 10, 2012 2:05 PM
SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC 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
Post #1371109
Posted Wednesday, October 10, 2012 2:52 PM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC 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
Post #1371124
Posted Wednesday, October 10, 2012 10:18 PM


Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: Yesterday @ 10:37 PM
Points: 1,172, Visits: 1,247
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


~ Lokesh Vij

Guidelines for quicker answers on T-SQL question
Guidelines for answers on Performance questions

Link to my Blog Post --> www.SQLPathy.com

Follow me @Twitter

Post #1371201
Posted Thursday, October 11, 2012 7:14 AM
SSC Journeyman

SSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC JourneymanSSC 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.
Post #1371453
Posted Thursday, October 11, 2012 7:41 AM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Yesterday @ 2:45 PM
Points: 8,567, Visits: 8,218
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 am certainly no expert and this is by no means a competition. This is definitely a better version than mine. Not sure why I used top instead of max.


_______________________________________________________________

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
Post #1371482
Posted Thursday, October 11, 2012 8:19 AM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC 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
Post #1371528
« Prev Topic | Next Topic »

Add to briefcase 12»»

Permissions Expand / Collapse