Tricky SQL Problem

Hello all,
I'm

very new to SQL, but find myself with this problem that i've been

working on for a while, but I just can't figure out how to work through

it.
I've got a database of appointments for vehicles. This database holds start time, month, day, year, end day month, year... etc.

I want to make a query that allows users to select a begining year, month day etc. and ending month year etc.

so i've got this query (I'm using PHP, so the $...'s are just $_Post variables.

so here's my query:
$query

= "SELECT * FROM `appointments` WHERE start_year BETWEEN $start_year

AND $end_year AND start_month >= $start_month AND end_month <=

$end_month AND start_day >= $start_day ORDER BY start_year,

start_month, start_day, start_time ASC";

When I try to run this

query, if the start month is january, and the end month is january

(regardless of year), it returns nothing (because nothing is between

january and january, and it's not factoring in the year change. How can

I factor in the year?)

Any input is greatly appreciated, I hope you understand where I'm running into trouble.
Thanks again!
-Robert

[1339 byte] By [Robert3234] at [2007-12-22]
# 1

Hi,

Can you post a (small) sample data set that illustrates the problem? I don't quite understand what you mean by "if the start month is january, and the end month is january (regardless of year), it returns nothing (because nothing is between january and january, and it's not factoring in the year change. How can I factor in the year?" I suspect your problem is resulting from NULLs in the data set.

I am curious - Why did you use the BETWEEN operator for year, but then use >=,<= for month and day?

You might also consider combining the separate date fragments (year, month, day, time) into a datetime value and let TSQL do the comparison on start/end datetime types.

Regards

CliffordDibble-MSFT at 2007-8-30 > top of Msdn Tech,SQL Server,Transact-SQL...
# 2

See my answer in this thread http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=580096&SiteID=17

something like this work for your current design, however as I mentioned in the other thread you should seriously consider changing your schema

SELECT ID, YearID, MonthID, ProductName

FROM Products

WHERE YEARID BETWEEN @StartYear AND @EndYear

AND 1 = CASE WHEN @StartYear = YEARID AND MonthID < @StartMonth THEN 0

WHEN @EndYear = YEARID AND MonthID > @EndMonth THEN 0

ELSE 1 END

Change the @StartYear to $startYEar

DavidLundell at 2007-8-30 > top of Msdn Tech,SQL Server,Transact-SQL...
# 3

hi there,

the solution is to combine your day, month, and year to build a valid

datetime as your start date same is true with your enddate

after that you can now compare the difference between dates

regards

joeydj at 2007-8-30 > top of Msdn Tech,SQL Server,Transact-SQL...
# 4

First off, format your query so you can see what it is doing:

SELECT *
FROM appointments
WHERE start_year BETWEEN $start_year AND $end_year
AND start_month >= $start_month AND end_month <= $end_month
AND start_day >= $start_day
ORDER BY start_year, start_month, start_day, start_time ASC

Then realize (as others have stated) that what you are trying to do does nt really make much sense. You are treating year, month, and day as if they are independent things. and they certainly are not. One of the reasons that date and time are part of a single value in SQL is that these are dependent upon one another. A case can be made to split off time, but generally only if you are interested in looking at things at the day level. Time is a hierarchy:

Year / Month / Day / Hour / Minute / etc.

So when you say you want to see everything in a year, that makes sense. But, when you ask:

Everything from 2005 to 2006 and January to February:

it is clear what the problem is. Independently you have said that the following matches:

2005 January, 2005 February (which you intended no doubt) AND 2006 January, 2006 February (which you would not have intended)

This is especially true when working with "Events" like appointments. You want to know the "relatively" exact date and time of the appointment, so you need to specifiy the complete starting point, and complete ending point.

So, to reiterate what has already been stated:

SELECT *
FROM appointments
WHERE cast(cast(start_year as char(4)) + cast(start_month as char(2)) + cast(start_day as char(2)) as datetime)
>= '20050101'
and cast(cast(start_year as char(4)) + cast(start_month as char(2)) + cast(start_day as char(2)) as datetime) < '20060301'

(I picked dates). It is typical in date ranges not use between, but rather specify the next day and say less than. This will include all times from the previous day in a datetime, (use dateadd to increment your last day is very typical usage). It also helps because you don't need to look up how many days February has (28, right?)

LouisDavidson at 2007-8-30 > top of Msdn Tech,SQL Server,Transact-SQL...

SQL Server

Site Classified