问题
I have a SQL statement to display data between two dates. I almost got it but there's a problem.
If I input March 1,2012 to March 7, 2012
.. it should show data with dates between the two.. but it also show all of the dates under March 2012.. but whenever I input March 10, 2012 to March 30, 2012 the SQL works perfectly.. any help will be appreciated. thanks
SELECT
agentname, noofcalls, qualified, booking, resched,
actualbooking, sales, remarks,
concat(month,' ',day,',',year) as 'date'
FROM
tblagents
WHERE
(month between '" & cbosmonth.Text & "' AND '" & cboemonth.Text & "')
AND (day between '" & cbosday.Text & "' AND '" & cboeday.Text & "')
AND (year between '" & cbosyear.Text & "' AND '" & cboeyear.Text & "')"
回答1:
you are doing string comparisons in each of your 'between'. Every number starting with a 1, a 2 or a 3, regardless of what follows it, i.e. 21, or 26, or 31, they are all lower than 7 if you look at them as strings. 1 to 30 works because you're only leaving 31 behind, and 30 < 31 as a String as well.
Do the concatenation first and then the between:
WHERE concat(month,' ',day,',',year)
BETWEEN concat(cbosmonth.Text,' ', cbosday.Text,' ',cbosyear.Text)
AND concat(cboemonth.Text,' ', cboeday.Text,' ',cboeyear.Text)
(check out for correct syntax, I'm just copy pasting from your question, not tried it)
BTW, unless you have a reason to, you probably should be storing the entire date in a single column with the right data time (datetime, timestamp, ...) and not three separated columns.
回答2:
That is the incorrect way to store a date in database. Change the date column to datatype date.
You could then do:
SELECT *
FROM table
WHERE bookingDate between to_date ('2012/03/01', 'yyyy/mm/dd')
AND to_date ('2012/03/07', 'yyyy/mm/dd');
回答3:
This approach is wrong.
In order for a date to be between two interval dates it does not have to have a day number between the two dates, e.g. (pseudocode)
date = May-25-2012; startDate = March-15-2012, endDate = June-01-2012
date
is clearly betweenstartDate
andendDate
, yetday(date)
is 25, which is not betweenday(startDate) = 15
andday(endDate) = 1
- more, as 15 is larger than 1, there are no numbers between them, so that condition will always be false
Similar example can be made for the month part of the date (e.g. date = May-25-2012; startDate = September-15-2010, endDate = Match-01-2015
)
You need to take the values for day, month, year, and construct a Date either in the application or on the server and use that to compare the values against.
To make a date from text fields in VB
Dim startDate = new DateTime(
Convert.ToInt32(cbosyear.Text),
Convert.ToInt32(cbosmonth.Text),
Convert.ToInt32(cbosday.Text))
Note that this will fail if the user enters, e.g. "some text" for the year value. You'll need to add some data validations to achieve that.
To make a datetime from parts in SQL Server, take a look here, there are quite a few techniques explained.
Also, you should always avoid just pasting values into the sql string, that's asking for sql injection problems. You should do something like this:
Dim command = new SqlCommand()
command.CommandText = "SELECT .... FROM tblagents where DATEFROMPARTS(year, month, day) between @startDate AND @endDate"
command.Parameters.AddWithValue("@startDate", startDate)
command.Parameters.AddWithValue("@endDate", endDate)
来源:https://stackoverflow.com/questions/13875824/between-clause-in-sql