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

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

Related

How to fetch hourly data for each day within two dates range in mysql?

Below my query:
SELECT DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d %H:%i:%s' ) AS timing, temperature, deviceid
FROM tempdata
WHERE deviceid =29
AND DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d' ) >= '2018-07-20'
AND DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d' ) <= '2018-07-27'
ORDER BY timing ASC
LIMIT 0 , 30
It can be by the following query
SELECT DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d %H:%i:%s' ) AS timing, AVG( temperature ) AS avg, deviceid
FROM tempdata
WHERE deviceid =29
AND DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d' ) >= '2018-07-20'
AND DATE_FORMAT( FROM_UNIXTIME( `temp_timing` ) , '%Y-%m-%d' ) <= '2018-07-27'
GROUP BY DATE( timing ) , HOUR( timing )
ORDER BY `timing` ASC
LIMIT 0 , 30

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.

Find the sum of an alias then group by

I understand that it is not possible to perform calculations on aliases directly, but is there a way that I could find the sum of my alias(totaltime)? Thanks for the help in advance.
SELECT *,
TIMEDIFF( time2, time1 ) ,
TIMEDIFF( time4, time3 ) ,
ADDTIME( TIMEDIFF( time2, time1 ) ,
TIMEDIFF( time4, time3 ) ) ,
TIME_FORMAT( ADDTIME( TIMEDIFF( time2, time1 ) ,
TIMEDIFF( time4, time3 ) ) , '%H:%i' )
AS totaltime
SUM(SELECT(totaltime)) AS sumtotal
FROM
timer
WHERE
groupid='100'
AND
MONTH(`date`) = MONTH(NOW())
GROUP BY userid
Just add another layer of abstraction ;)
SELECT TIME_FORMAT(sec_to_time(sum(timecard.totaltime)),'%H:%i' ) FROM
(
SELECT *,
TIMEDIFF( out_time, in_time ) ,
TIMEDIFF( lunch_in, lunch_out ) ,
ADDTIME( TIMEDIFF( out_time, in_time ) , TIMEDIFF( lunch_in, lunch_out ) ) ,
ADDTIME( TIMEDIFF( out_time, in_time ) ,
TIMEDIFF( lunch_in, lunch_out ) )
AS totaltime
FROM
timecard
WHERE
comp_id='129'
AND
MONTH(`date`) = MONTH(NOW())
GROUP BY emp_id
) timecard
Link to fiddle: http://sqlfiddle.com/#!2/b33d8/16/0

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.