sql show date between start date and end date - mysql

I would like to know how I can compare a birthday date between a start date and end date.
For now I use this:
select *
from users
where dayofyear(birthday) between dayofyear(start_date) and dayofyear(end_date);
the problem is if start_date = 2011-12-01 and end_date = 2012-01-01 then I get no results.
If the user birthday is 1931-12-12 any year, it must be in the query result.
For now i get no result.
someone have a hint to resolve this kind of issue? Thanks.

The following is a little ugly but it accounts for all birthdays that occur in the time span between start_date and end_date. If the time span is greater than a year then it basically returns everyone because everyone has a birthday somewhere in that time span. If it is less than a year but start and end are on different years it uses two between clauses to capture both the start time to the end of the year and the start of the year to the end time. This query also assumes that start_date <= end_date.
As long as you have an index on DAYOFYEAR( birthday ) this query is performant despite it's appearance.
SET #start_date = '2011-12-01';
SET #end_date = '2012-01-01';
SELECT * FROM users
WHERE DAYOFYEAR( birthday )
BETWEEN IF( YEAR( #end_date ) - YEAR( #start_date ) > 1, 1,
IF( YEAR( #end_date ) - YEAR( #start_date ) > 0,
IF( DAYOFYEAR( #start_date ) <= DAYOFYEAR( #end_date ), 1,
DAYOFYEAR( #start_date ) ),
DAYOFYEAR( #start_date ) ) )
AND IF( YEAR( #end_date ) - YEAR( #start_date ) > 1, 366,
IF( YEAR( #end_date ) - YEAR( #start_date ) > 0, 366,
DAYOFYEAR( #end_date ) ) )
OR DAYOFYEAR( birthday )
BETWEEN IF( YEAR( #end_date ) - YEAR( #start_date ) > 1, 1,
IF( YEAR( #end_date ) - YEAR( #start_date ) > 0, 1,
DAYOFYEAR( #start_date ) ) )
AND IF( YEAR( #end_date ) - YEAR( #start_date ) > 1, 366,
IF( YEAR( #end_date ) - YEAR( #start_date ) > 0,
IF( DAYOFYEAR( #start_date ) <= DAYOFYEAR( #end_date ), 366,
DAYOFYEAR( #end_date ) ),
DAYOFYEAR( #end_date ) ) );

Related

check either startdate or end date is in last week

I want to check either startdate or enddate is in last week.I want to display the rows which has commRunStart or commRunEnd date is in last week .
SELECT A.commRunStart, A.commRunEnd FROM `commRuns` AS A
WHERE A.commRunStart >= CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) +6 DAY
OR A.commRunEnd < CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) -1 DAY
SELECT A.commRunStart, A.commRunEnd FROM `commRuns` AS A
WHERE (A.commRunStart >= CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) +6 DAY
AND A.commRunStart < CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) -1 DAY )
OR (A.commRunEnd >= CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) +6 DAY
AND A.commRunEnd < CURDATE( ) - INTERVAL DAYOFWEEK( CURDATE( ) ) -1 DAY )

how to compare equals and less than today's date to a given date in mysql

How can I compare (equals and less than) today's date to a given date in MYSQL ? I am getting problems when using <=. This is not working when I use =. I want both less than and equal.
<%
rs=st.executeQuery("select approcode,approemail,appromon,approvemon,approtue,approvetue,approwed,approvewed,approthr,approvethr,approfri,approvefri,approsat,approvesat,commen,months,SUM(nol) from `pushkalit`.`approval`WHERE (CONVERT( `approcode` USING utf8 ) LIKE '%"+user+"%')
AND DATE( NOW( ) ) <= DATE( appromon ) OR
DATE( NOW( ) ) <= DATE( approtue ) OR
DATE( NOW( ) ) <= DATE( approwed ) OR
DATE( NOW( ) ) <= DATE( approthr ) OR
DATE( NOW( ) ) <= DATE( approfri ) OR
DATE( NOW( ) ) <= DATE( approvesat )");
%>
Wrong direction, you're currently doing equals and MORE than today date. It should be NOW( ) >= DATE(....
if i understand correctly you should do some change like: now()>=date()
DATE( NOW( ) ) >= DATE( appromon )
sample sqlfiddle

SQL exception Parameter index out of range

I'm sending 4 values for the sql query through a jaggery script. Here is the sql query:
SELECT full_name , sum( amount ) AS total
FROM hourlyusage , user
WHERE DAY = DATE( DATE_SUB( NOW( ) , INTERVAL ? HOUR ) )
AND HOUR BETWEEN HOUR( DATE_SUB( NOW( ) , INTERVAL ? HOUR ) )
AND HOUR( DATE_SUB( NOW( ) , INTERVAL 1 HOUR ) )
AND hourlyusage.userIp = user.ip_address
AND (user.full_name LIKE '%?%' OR user.user_name LIKE '%?%') GROUP BY full_name
But it gives an exception like this.
Nested Exception:-
java.sql.SQLException: Parameter index out of range (3 > number of parameters, which is 2).
What would be the reason for that?
SELECT full_name , sum( amount ) AS total
FROM hourlyusage , user
WHERE DAY = DATE( DATE_SUB( NOW( ) , INTERVAL ? HOUR ) )
AND HOUR BETWEEN HOUR( DATE_SUB( NOW( ) , INTERVAL ? HOUR ) )
AND HOUR( DATE_SUB( NOW( ) , INTERVAL 1 HOUR ) )
AND hourlyusage.userIp = user.ip_address
AND (user.full_name LIKE ? OR user.user_name LIKE ?) GROUP BY full_name
You cannot use wildcard in the sql query so try to remove the wildcard from the sql and add it to the value.As you have done '%?%' in sql says that you need global match.Do that in your value not in sql query.

Issue with SQL getting Upcoming Birthdays

Can anyone fix the following SQL code, which gets upcoming birthdays:
SELECT *
FROM personal
WHERE 1 = ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL :interval DAY ) , dob ) / 365.25 ) ) -
( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL -1 DAY ) , dob ) / 365.25 ) )
ORDER BY MONTH( dob ), DAY( dob )
LIMIT :rangeStart,:limit
It works aside from there is a bug with the ordering if the year rolls over. E.g. your in December checking ahead 1 month, then January birthday will get ordered before December.
I've seen a few posts on here about doing this, but none of them seem to get this part correct. I tried using the following ORDER BY clause, from another post and which seemed to work for someone else, but when I run it I get a syntax error:
ORDER BY ( MONTH(dob) > MONTH(NOW() OR ((MONTH(dob) = MONTH(NOW()) AND DAY(dob) >= DAY(NOW()) DESC, MONTH(dob), DAY(dob)
Updated answer ...
Thought of a cleaner way to accomplish this:
SELECT *
FROM (
SELECT *
,DATE_ADD( MAKEDATE( YEAR( NOW() ), DAYOFYEAR( dob ) )
,INTERVAL IF( DAYOFYEAR( dob ) < DAYOFYEAR( NOW() ), 1, 0 ) YEAR
)
AS next_birthday
FROM personal
) a
WHERE a.next_birthday < DATE_ADD( NOW(), INTERVAL :interval DAY )
ORDER BY a.next_birthday ASC
LIMIT :rangeStart,:limit
Explanation: next_birthday is calculated by taking this year's birthday and adding either 1 or 0 years to it depending on whether or not the birthday has already occurred this year - determined by IF( DAYOFYEAR( dob ) < DAYOFYEAR( NOW() ), 1, 0 ).
See it in action in SQLFiddle at http://sqlfiddle.com/#!9/b6471/1. Play with the number of days to see January after December.
Original answer ...
Add the following to your SELECT:
SELECT *
, CASE WHEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ) >= CURRENT_DATE
THEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) )
ELSE DATE_ADD( MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ), INTERVAL 1 YEAR )
END AS next_birthday
then
ORDER BY next_birthday ASC
Rewriting your original query you get something like:
SELECT a.*
FROM ( SELECT *
, CASE WHEN DAYOFYEAR( dob ) >= DAYOFYEAR( CURRENT_DATE )
THEN MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) )
ELSE DATE_ADD( MAKEDATE( YEAR( CURRENT_DATE ), DAYOFYEAR( dob ) ), INTERVAL 1 YEAR )
END AS next_birthday
FROM personal
) a
WHERE a.next_birthday < DATE_ADD( CURRENT_DATE, INTERVAL :interval DAY )
ORDER BY a.next_birthday ASC
LIMIT :rangeStart,:limit
I've now found a solution. For those that would like to know, the final code is:
SELECT *, DATE_ADD( dob, INTERVAL YEAR( FROM_DAYS( DATEDIFF( NOW( ), dob) -1 ) ) + 1 YEAR) AS next_birthday
FROM personal
WHERE 1 = ( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL :interval DAY ) , dob ) / 365.25 ) ) -
( FLOOR( DATEDIFF( DATE_ADD( DATE( NOW( ) ) , INTERVAL -1 DAY ) , dob ) / 365.25 ) )
ORDER BY next_birthday ASC
LIMIT :rangeStart,:limit
I haven't tested it fully, but on simple tests it works.

MYSQL REPORTING

is there a more efficent way to get rows fro ma table from the current week, last week, current month and current year to this
// current month
SELECT * FROM crm_tasks WHERE YEAR( date_completed ) = YEAR( CURDATE( ) ) AND MONTH( date_completed ) = MONTH( CURDATE( ) )
// current week
SELECT * FROM crm_tasks WHERE YEAR( date_completed ) = YEAR( CURDATE( ) ) AND WEEK( date_completed ) = WEEK( CURDATE( ) )
// last week
SELECT * FROM crm_tasks WHERE YEAR( date_completed ) = YEAR( CURDATE( ) ) AND WEEK( date_completed ) = WEEK( CURDATE( ) ) - 1
// current year
SELECT * FROM crm_tasks WHERE YEAR( date_completed ) = YEAR( CURDATE( ) )
You should be able to use a query similar to this
SELECT * FROM crm_tasks
WHERE date_completed >= #FirstDayOfYear AND date_completed < #FirstDayOfNextYear
Where #FirstDayOfYear and #FirstDayOfNextYear are filled in appropriately. If you have an index on date_created, this should work reasonably fast. This can be altered for any period you want to use.