MYSQL next month query not working - mysql

I hope someone can help me with my query. I am trying to get all the rows from a mysql database where 'end' falls inside next calendar month. At the moment my query is only pulling rows where 'start' is inside the next calendar month.
if (! empty($_GET['skill'])) $whereClauses[] ="skill LIKE('%".mysqli_real_escape_string($db_conx,$_GET['skill'])."%')";
if (!empty($_GET['start']))
if ($_GET['start'] == "today") {
$whereClauses[] = "START = CURDATE()";
}
else if ($_GET['start'] == "tomorrow") {
$whereClauses[] = "START = DATE_ADD( CURDATE( ) , INTERVAL( 9 - IF( DAYOFWEEK( CURDATE( ) ) =1, 8, DAYOFWEEK( CURDATE( ) ) ) ) DAY )";
}
else if ($_GET['start'] == "next_week") {
$whereClauses[] = "START = DATE_ADD( CURDATE( ) , INTERVAL( 9 - IF( DAYOFWEEK( CURDATE( ) ) =1, 8, DAYOFWEEK( CURDATE( ) ) ) )
DAY )";
}
else if ($_GET['start'] == "this_month") {
$whereClauses[] = "START BETWEEN DATE_SUB( CURDATE( ) , INTERVAL( DAY( CURDATE( ) ) -1 ) DAY ) AND LAST_DAY( NOW( ) )";
}
else if ($_GET['start'] == "next_month") {
$whereClauses[] = "start BETWEEN DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)),INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)))-1 DAY) AND LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH))";
}
else if ($_GET['start'] == "in_future") {
$whereClauses[] = "START > CURDATE()";
}
and then
$sql="SELECT * FROM mytable " .$where."";
What am I doing wrong?

The answer was this
SELECT * FROM mytable WHERE
FLOOR(start/100)<=FLOOR(NOW()/100000000)+1 AND
FLOOR( end/100)>=FLOOR(NOW()/100000000)+1
Courtesy of Cars10 on this page

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 )

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.

SELECT COUNT + (SELECT COUNT FROM TABLE1 WHERE ) FROM TABLE1 in Zend

How to write this query in Zend
SELECT COUNT( 1 ) AS `NoOfQueries` , DATE( CONVERT_TZ( FROM_UNIXTIME( poocher.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) AS `Dat` , COUNT( 1 ) + (
SELECT COUNT( 1 )
FROM tblsmsuser poocherb4
WHERE DATE( CONVERT_TZ( FROM_UNIXTIME( poocherb4.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) <= DATE_SUB( `Dat` , INTERVAL 1
DAY ) ) AS cumulative_sum
FROM tblsmsuser poocher
GROUP BY `Dat`
What I have tried is
$this->select = new Zend_Db_Select($this->db);
$selctSub = $this->select->from("tblsmsuser",array("count(1)"))->where("DATE( CONVERT_TZ( FROM_UNIXTIME( tblsmsuser.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) <= DATE_SUB( Dat , INTERVAL 1 DAY )");
echo $select_query_ans = $this->select->from(array("poocher" =>"tblsmsuser"),array("NoOfQueries"=>"count(1)","Dat"=>"DATE( CONVERT_TZ( FROM_UNIXTIME( poocher.cdate,'%Y-%m-%d %T' ),'-9:30','+00:00' ) )","cumulative_sum"=>"count(1) + (".$selctSub.")"))->group("Dat");
Output
SELECT count(1) AS `NoOfQueries`, DATE( CONVERT_TZ( FROM_UNIXTIME( poocher.cdate,'%Y-%m-%d %T' ),'-9:30','+00:00' ) ) AS `Dat`, count(1) + (SELECT count(1) AS `NoOfQueriesb4` FROM `tblsmsuser` AS ```poocherb4`` WHERE (DATE( CONVERT_TZ( FROM_UNIXTIME( poocherb4.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) <= DATE_SUB( Dat , INTERVAL 1 DAY )))`, count(1) AS `NoOfQueriesb4` FROM `tblsmsuser` AS `poocher` INNER JOIN `tblsmsuser` AS `` WHERE (DATE( CONVERT_TZ( FROM_UNIXTIME( poocherb4.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) <= DATE_SUB( Dat , INTERVAL 1 DAY )) GROUP BY `Dat`
Here is the code which worked for me
$this->select = new Zend_Db_Select($this->db);
$selctSub = $this->select->from("tblsmsuser",array("count(1)"))->where("DATE( CONVERT_TZ( FROM_UNIXTIME( tblsmsuser.cdate, '%Y-%m-%d %T' ) , '-9:30', '+00:00' ) ) <= DATE_SUB( Dat , INTERVAL 1 DAY )");
$this->select = new Zend_Db_Select($this->db); //ADDED line
echo $select_query_ans = $this->select->from(array("poocher" =>"tblsmsuser"),array("NoOfQueries"=>"count(1)","Dat"=>"DATE( CONVERT_TZ( FROM_UNIXTIME( poocher.cdate,'%Y-%m-%d %T' ),'-9:30','+00:00' ) )","cumulative_sum"=>"count(1) + (".$selctSub.")"))->group("Dat");

sql show date between start date and end date

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 ) ) );

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.