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.
Related
Highcharts dont display statistics with MySQL Query
It Works:
$this->db->query("SELECT COUNT( gt ) as sayi , FROM_UNIXTIME( tarih, '$periyot' ) AS gun
FROM sayigoruntu
WHERE tarih >= DATE_SUB( CURDATE( ) , INTERVAL 1 MONTH ) and gt='$gt'".$sqlek."
GROUP BY gun
ORDER BY gun");
Output:
[[3582],[2062],[140],[4425],[294]]
$this->db->last_query() Result:
SELECT COUNT( gt ) as sayi , FROM_UNIXTIME( tarih, '%Y.%m.%d' ) AS gun FROM sayigoruntu WHERE tarih >= DATE_SUB( CURDATE( ) , INTERVAL 1 MONTH ) and gt='0' GROUP BY gun ORDER BY gun
This works without problems but this doesn't work (PHP):
if($siteid !=''){
$sqlek="and sid='".$siteid."'";
}
SQL Query:
SELECT COUNT( gt ) as sayi , FROM_UNIXTIME( tarih, '$periyot' ) AS gun
FROM sayigoruntu
WHERE tarih >= DATE_SUB( CURDATE( ) , INTERVAL 1 MONTH ) and gt='$gt'".$sqlek."
GROUP BY gun
ORDER BY gun
Output:
[[3582],[2062],[140],[4425],[294]]
$this->db->last_query() result:
SELECT COUNT( gt ) as sayi , FROM_UNIXTIME( tarih, '%Y.%m.%d' ) AS gun FROM sayigoruntu WHERE tarih >= DATE_SUB( CURDATE( ) , INTERVAL 1 MONTH ) and gt='0' GROUP BY gun ORDER BY gun
Same Output, Same Queries but not working. Error reason maybe ".$sqlek." on MySQL Query.
Is MySQL Query Right Or is this a Highcharts Error?
Your form is incorrect, it should be array of numbers or array of arrays but including x/y. Not an array of arrays with single value. How you refer your data to javascript?
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.
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.
I am trying to get the total of all orders of each seller per year, month, and day using this sql. I am still wrapping my head around joins, but from what I know i thought this should work
SELECT sellers.username, sellers.registerDate, sellers.sellerid,
orders.orderPrice, orders.orderDate, orders.sellerid,
count(orders.orderPrice) AS products, SUM( orders.orderPrice ) AS total,
FROM `sellers`
JOIN
`orders`,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE YEAR( orderDate ) = YEAR( CURDATE( ) ) ) AS year,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE MONTH( orderDate ) = MONTH( CURDATE( ) ) ) AS month,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE orderDate = CURDATE() ) AS day
ON orders.sellerid = sellers.sellerid
GROUP BY sellers.username
HAVING total > 0
ORDER BY total desc
LIMIT 0 , 4
But it gives me an error (#1064 - near 'ON orders.sellerid = sellers.sellerid GROUP BY sellers.username HAVING' at line 9)
You need to set ON clause on every join table not only the lastone.
Regards
JOIN
`orders` ON ??? = ???,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE YEAR( orderDate ) = YEAR( CURDATE( ) ) ) AS year ON orders.sellerid = sellers.sellerid,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE MONTH( orderDate ) = MONTH( CURDATE( ) ) ) AS month ON orders.sellerid = sellers.sellerid,
(SELECT SUM( orders.orderPrice ) FROM `orders` WHERE orderDate = CURDATE() ) AS day
ON orders.sellerid = sellers.sellerid
I have a MYSQL table with two columns, timestamp and span. timestamp is a unix-timestamp, while span is an integer.
I want to select all rows where the timestamp is between the current time +- half the span.
Eg. if the current time is 23:00, then I want all rows where the timestamp time is between 21 and 01. The issue is of-course that all the timestamps are from different days.
TO CLARIFY, I don't care about the date only the time
I've figured out a way to do this, but it seems like such a hack. I'm sure that someone with more MYSQL knowledge could show me a prettier way to do this.
SELECT *
FROM table
WHERE (
TIME( DATE_SUB( CURDATE( ) , INTERVAL( span /2 ) HOUR ) ) <= TIME( DATE_ADD( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
AND (
TIME( FROM_UNIXTIME( timestamp ) ) >= TIME( DATE_SUB( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
AND TIME( FROM_UNIXTIME( timestamp ) ) <= TIME( DATE_ADD( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
)
)
OR (
TIME( DATE_SUB( CURDATE( ) , INTERVAL( span /2 ) HOUR ) ) >= TIME( DATE_ADD( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
AND (
TIME( FROM_UNIXTIME( timestamp ) ) >= TIME( DATE_SUB( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
OR TIME( FROM_UNIXTIME( timestamp ) ) <= TIME( DATE_ADD( CURDATE( ) , INTERVAL( span /2 ) HOUR ) )
)
)
Two options I recommend.
Benchmark your "hack" query and see if that is faster than running two MySQL queries. Eg: One query to get your target row, another query to get results with ±1/2 span.
Write a proper MySQL stored procedure. This is effectively option (1) but all done inside the DB.
Another option I don't recommend, based on past pain, is to use MySQL variables to effectively do two selects avoiding the stored procedure, eg: http://dev.mysql.com/doc/refman/5.0/en/user-variables.html. This approach was common back in the old days of PHP/MySQL apps.
In my experience odds are good option (1) is both fast enough and readable.
Didn't really find a pretty solution, but this is how i ended up doing it.
SELECT *
FROM table
WHERE date_add( from_unixtime( timestamp ) , INTERVAL datediff( now( ) , from_unixtime( timestamp ) ) DAY )
BETWEEN date_sub( now( ) , INTERVAL (span/2) HOUR )
AND date_add( now( ) , INTERVAL (span/2) HOUR )
OR date_add( from_unixtime( timestamp ) , INTERVAL datediff( now( ) , from_unixtime( timestamp ) ) -1 DAY )
BETWEEN date_sub( now( ) , INTERVAL (span/2) HOUR )
AND date_add( now( ) , INTERVAL (span/2) HOUR )