School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 300,475 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,744 people online right now. Registration is fast and FREE... Join Now!




Problem with Querying between two times

 

Problem with Querying between two times, CF SQL is 1899 but MSSQL is 1800

xheartonfire43x

23 Apr, 2009 - 09:41 AM
Post #1

D.I.C Regular
***

Joined: 22 Dec, 2008
Posts: 260



Thanked: 2 times
My Contributions
I am trying to make a calendar... still. And I am working on the week view of it. I need to query the table between two hours, but SQL can't just have a time... it needs a date and a time. So when you input just a time into the table MSSQL uses the date 1900-1-1. When you try to Query from CF using just a time it puts 1899-30-30. So is it possible to have the SQL completely disregard the date?

My code so far is:
CODE

<cfquery name="getHour" datasource="#CRE_UserDatabase#" username="#CRE_Username#" password="#CRE_Password#">
    SELECT id,subject,location,category,starttime FROM calendar
    WHERE username = <cfqueryparam value="#session.myusername#"> AND startdate = <cfqueryparam value="#loopcurrentday#" cfsqltype="cf_sql_date"> AND starttime BETWEEN '#createtime(hour(loopcurrenthour),0,0)#' AND '#createtime(hour(dateAdd("h",1,loopcurrenthour)),59,59)#'
</cfquery>
<cfdump var="#getHour#" expand="no">


I know that if I really wanted to is add a dateadd function but I am not entirely sure that CF will always uses 1899-30-30 as the date.

User is offlineProfile CardPM
+Quote Post


sansclue

RE: Problem With Querying Between Two Times

23 Apr, 2009 - 12:01 PM
Post #2

D.I.C Regular
***

Joined: 21 Nov, 2007
Posts: 316



Thanked: 28 times
My Contributions
QUOTE(xheartonfire43x @ 23 Apr, 2009 - 09:41 AM) *

MSSQL uses the date 1900-1-1. When you try to Query from CF using just a time it puts 1899-30-30. ...


I don't know how you are getting 1899-30-30. But you are correct that CF uses a different epoch than MS SQL: 1899-12-30 versus 1900-01-01. Basically you are choices are to either pass in the right date value from CF, or let ms sql do the conversions.

I usually store the date _and_ time together, rather than separately. I have found it is easier to work with in most cases. (That is option #1), some other options are:

1. Store the date with the start/end time, then pass in the date _and_ time
<cfqueryparam value="#fullDateAndTime#" cfsqltype="cf_sql_timestamp">

2. Pass in a value with the same epoch as ms sql.
ie Create a CF date/time value using 1900-1-1 as the date

3. Pass in a string and let ms sql do the conversion
ie WHERE TimeColumn >= '07:00:00'

4. Possibly use ms sql's datePart functions
ie WHERE DatePart(h, TimeColumn) >= 7 AND ...


IMO #2 - 4 are a bit klunky and have some disavantages.
User is offlineProfile CardPM
+Quote Post

xheartonfire43x

RE: Problem With Querying Between Two Times

23 Apr, 2009 - 12:27 PM
Post #3

D.I.C Regular
***

Joined: 22 Dec, 2008
Posts: 260



Thanked: 2 times
My Contributions
QUOTE(sansclue @ 23 Apr, 2009 - 12:01 PM) *

I don't know how you are getting 1899-30-30. But you are correct that CF uses a different epoch than MS SQL: 1899-12-30 versus 1900-01-01. Basically you are choices are to either pass in the right date value from CF, or let ms sql do the conversions.

I usually store the date _and_ time together, rather than separately. I have found it is easier to work with in most cases. (That is option #1), some other options are:

1. Store the date with the start/end time, then pass in the date _and_ time
<cfqueryparam value="#fullDateAndTime#" cfsqltype="cf_sql_timestamp">

2. Pass in a value with the same epoch as ms sql.
ie Create a CF date/time value using 1900-1-1 as the date

3. Pass in a string and let ms sql do the conversion
ie WHERE TimeColumn >= '07:00:00'

4. Possibly use ms sql's datePart functions
ie WHERE DatePart(h, TimeColumn) >= 7 AND ...


IMO #2 - 4 are a bit klunky and have some disavantages.


I got it working perfectly with datePart(). Rather than doing a BETWEEN statement I did an = one.

CODE

<cfquery name="getHour" datasource="#CRE_UserDatabase#" username="#CRE_Username#" password="#CRE_Password#">
    SELECT id,subject,location,category,starttime FROM calendar
    WHERE username = <cfqueryparam value="#session.myusername#">
    AND startdate = <cfqueryparam value="#loopcurrentday#" cfsqltype="cf_sql_date">
    AND DATEPART(hh,starttime) = <cfqueryparam value="#datepart('h',createtime(hour(loopcurrenthour),0,0))#">
</cfquery>


Now it returns everything on that hour.
User is offlineProfile CardPM
+Quote Post

sansclue

RE: Problem With Querying Between Two Times

23 Apr, 2009 - 12:38 PM
Post #4

D.I.C Regular
***

Joined: 21 Nov, 2007
Posts: 316



Thanked: 28 times
My Contributions
QUOTE

DATEPART(hh,starttime) = <cfqueryparam value="#datepart('h',createtime(hour(loopcurrenthour),0,0))#"
(don't forget the cfsqltype here)
>


Yes, unfortunately that usually kills any possibility of ms sql using an index on that column. Simplicity at the cost of performance. But if your database is small, it may not matter to you .


User is offlineProfile CardPM
+Quote Post

xheartonfire43x

RE: Problem With Querying Between Two Times

24 Apr, 2009 - 07:04 AM
Post #5

D.I.C Regular
***

Joined: 22 Dec, 2008
Posts: 260



Thanked: 2 times
My Contributions
QUOTE(sansclue @ 23 Apr, 2009 - 12:38 PM) *

QUOTE

DATEPART(hh,starttime) = <cfqueryparam value="#datepart('h',createtime(hour(loopcurrenthour),0,0))#"
(don't forget the cfsqltype here)
>


Yes, unfortunately that usually kills any possibility of ms sql using an index on that column. Simplicity at the cost of performance. But if your database is small, it may not matter to you .


What if I queried the table, pulled everything by Username first and order it by starttime and then pulled stuff from that query based on the time... would that run faster?
User is offlineProfile CardPM
+Quote Post

sansclue

RE: Problem With Querying Between Two Times

24 Apr, 2009 - 07:32 AM
Post #6

D.I.C Regular
***

Joined: 21 Nov, 2007
Posts: 316



Thanked: 28 times
My Contributions
QUOTE(xheartonfire43x @ 24 Apr, 2009 - 07:04 AM) *

What if I queried the table, pulled everything by Username first and order it by starttime and then pulled stuff from that query based on the time... would that run faster?


No, the other method would still be faster. In large part because it would pull much less information ie 3 or 4 records as opposed to every record in the table.

This is more about optimization and writing queries that help the database perform more efficiently. The performance differences would be far less noticeable with a small database. But it is good to get into the habit of writing queries that scale well.


User is offlineProfile CardPM
+Quote Post

xheartonfire43x

RE: Problem With Querying Between Two Times

24 Apr, 2009 - 07:45 AM
Post #7

D.I.C Regular
***

Joined: 22 Dec, 2008
Posts: 260



Thanked: 2 times
My Contributions
QUOTE(sansclue @ 24 Apr, 2009 - 07:32 AM) *

QUOTE(xheartonfire43x @ 24 Apr, 2009 - 07:04 AM) *

What if I queried the table, pulled everything by Username first and order it by starttime and then pulled stuff from that query based on the time... would that run faster?


No, the other method would still be faster. In large part because it would pull much less information ie 3 or 4 records as opposed to every record in the table.

This is more about optimization and writing queries that help the database perform more efficiently. The performance differences would be far less noticeable with a small database. But it is good to get into the habit of writing queries that scale well.


But I feel that if I first pull by the Username and the CurrentDate then pull from that by the StartTime it will run faster because the DB could have 1000 records but out of that 1000 records it will only need to pull the ones that are for that User and then the startdate bringing it down to maybe 10... if that.
User is offlineProfile CardPM
+Quote Post

sansclue

RE: Problem With Querying Between Two Times

24 Apr, 2009 - 09:54 AM
Post #8

D.I.C Regular
***

Joined: 21 Nov, 2007
Posts: 316



Thanked: 28 times
My Contributions
QUOTE(xheartonfire43x @ 24 Apr, 2009 - 07:45 AM) *

But I feel that if I first pull by the Username and the CurrentDate then pull from that by the StartTime it will run faster because the DB could have 1000 records but out of that 1000 records it will only need to pull the ones that are for that User and then the startdate bringing it down to maybe 10... if that.


Yes, retrieving 10 for a particular date would be quicker than pulling all 1000 records. But you are still pulling more information than you need. Plus you are doing this in a loop (which is not very efficient to begin with), so it all adds up. It is fine for one user, but add in many users and you end up putting a lot of unnecessary load on the database.

Really, it is better to let the database do the work and not try and out-think it. There is lot that goes on behind the scenes with the various database engines. It is a deep topic, and the behavior is not always intutive. I have done some reading on it, and found it is often not what I would expect at all, and it usually a lot more complicated than I thought.

But right now you are talking about a table with only 1000 records. So the chances are even a SELECT * would perform okay. Even if the query is not as efficient as it could be, databases are smarter and better at this. The best thing to do is try and write queries in a way that scales well, and let the database take it from there. Anything else should be handled by a dba, so you don't end up making things worse in an attempt to "fix" something.

In any case, you could still re-work the query so it doesn't use functions. That is one of the options I mentioned above.

Update To give you an idea of the complexity of this topic:
http://www.mssqltips.com/tip.asp?tip=1236
http://support.microsoft.com/kb/110352
http://blogs.msdn.com/queryoptteam/


This post has been edited by sansclue: 24 Apr, 2009 - 09:58 AM
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/8/09 03:21AM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month