MYSQL Select by this week with index - mysql

User can see what they have uploaded in this week. I have below code in line:
Is this correct?
SELECT *
FROM images
WHERE userid = '$userid'
AND uploadeddate >= CURDATE() - INTERVAL WEEKDAY(day) DAY
AND uploadeddate < CURDATE() - INTERVAL WEEKDAY(day) DAY + INTERVAL 7 DAY
ORDER BY uploadeddate DESC
I have create index for (userid, uploadeddate) .

For your original query to work day needs to be in the database you're querying (or set as a variable) and it needs to be in a MySQL date '0000-00-00' or date time '0000-00-00 00:00:00' formats.
WEEKDAY() returns 0-6 for the date entered.
$first; //is earliest offset in the range
$last; //is the latest offset in the range
SELECT * FROM images WHERE userid = '$userid'
AND uploadeddate > CURDATE() - INTERVAL $first DAY
AND uploadeddate < CURDATE() - INTERVAL $last DAY
ORDER BY uploadeddate DESC
So a query like this would return results for last week.
SELECT * FROM images WHERE userid = '$userid' AND
uploadeddate > CURDATE() - INTERVAL 14 DAY
AND uploadeddate < CURDATE() - INTERVAL 7 DAY
ORDER BY uploadeddate DESC

Related

How DO I fetch last Week and current week

How do I fetch last week data from monday time (00:00:01) and end on sunday time (23:59:59)...
same as this current week from monday time (00:00:01) and end on sunday time (23:59:59)
WHat I tried!
$query = "SELECT users.name,count(*) as count,
campaign.campaign_name,
campaign.payout_cost*count(*) as totalPrice
FROM users
JOIN transactions on users.uid=transactions.uid
JOIN campaign on campaign.campaign_id_id=transactions.campaign_id
WHERE uid=$uid
AND `date` >= DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())+6 DAY)
AND `date` < DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY campaign.campaign_name_name ";
You are on the right track by avoiding functions like week() on the column -- that just messes up the optimizer. On the other hand, the uid parameter should be passed as a parameter rather than munging the query string.
You want to use the weekday() function because you want weeks to start on a Monday. Just some arcaneness of MySQL: weekday() returns 0 for Monday whereas dayofweek() returns 2 for Monday.
So, the logic for the current week would be:
date >= curdate() - interval weekday(curdate()) day and
date < curdate() + interval 7 - weekday(curdate()) day
For last week, this would be:
date >= curdate() - interval 7 + weekday(curdate()) day and
date < curdate() + interval - weekday(curdate()) day
Notes that curdate() (or current_date) returns the current date with no time component, so no date() is required.
Couple of ways to do it...
select data from tableName
where date between date_sub(now(),INTERVAL 1 WEEK) and now();
select data FROM tableName
wherdate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
You can use WEEK() function, which returns the week number for a given date, by adding
AND WEEK(date-INTERVAL 1 DAY) = WEEK(NOW()) - 1 to get current week's data starting from monday upto sunday,
and
AND WEEK(date-INTERVAL 1 DAY) = WEEK(NOW()) - 2 for the previous week's data
into the WHERE condition after WHERE uid=$uid
such as
$query = "SELECT c.campaign_name,
COUNT(*) as total_count,
SUM(c.payout_cost) as total_payout
FROM transactions t
JOIN campaign c
ON c.campaign_id = t.campaign_id
WHERE uid = $uid
AND WEEK(date - INTERVAL 1 DAY) = WEEK(NOW()) - 1
GROUP BY c.campaign_name ";
and replace WEEK(NOW()) - 1 with WEEK(NOW()) - 2, also
Demo

MySQL 5.6 - select results where the most recent of multiple datetime columns is 1 month ago at least

I have a table with multiple datetime columns in a mySQL 5.6 database.
email_id
email_sent_date (datetime)
email_replied_date (datetime)
email_bounced_date(datetime)
email_archived (datetime)
I want to retrieve all emails where the latest datetime of the group (email_sent_date,email_replied_date, email_bounced_date, email_archived) is at least 1 month ago from today.
I would like to do something like this, even though i think I can't use this max(), but you'll get a sense of what I am trying to achieve:
SELECT *
FROM table
WHERE MAX(email_sent_date,email_replied_date, email_bounced_date, email_archived) <= CURDATE() - INTERVAL 30 DAY
How to achieve this ?
You want the function greatest(), not max():
SELECT *
FROM table
WHERE GREATEST(email_sent_date, email_replied_date, email_bounced_date, email_archive) <= CURDATE() - INTERVAL 30 DAY;
Note: If any of the values are NULL, then the row will be filtered out.
I prefer explicit comparisons because I think the logic is easier to follow:
SELECT *
FROM table
WHERE email_sent_date <= CURDATE() - INTERVAL 30 DAY AND
email_replied_date <= CURDATE() - INTERVAL 30 DAY AND
email_bounced_date <= CURDATE() - INTERVAL 30 DAY AND
email_archive <= CURDATE() - INTERVAL 30 DAY;
EDIT:
Handling NULL values requires explicit checks. Perhaps:
SELECT *
FROM table
WHERE (email_sent_date <= CURDATE() - INTERVAL 30 DAY OR email_sent_date IS NULL) AND
(email_replied_date <= CURDATE() - INTERVAL 30 DAY OR email_replied_date IS NULL) AND
(email_bounced_date <= CURDATE() - INTERVAL 30 DAY OR email_bounced_date IS NULL) AND
(email_archive <= CURDATE() - INTERVAL 30 DAY OR email_archive IS NULL);

mysql select between two dates has odd behavior

I am selecting all records between NOW() and specific X day interval and came across this odd behavior that I don't understand.
I am checking 24 hours into the future and 24 hours into the past:
select * from table where date between NOW() and NOW() + 1 interval day; //works
select * from table where date between NOW() and NOW() - 1 interval day; //no records
But if I reverse the between call:
select * from table where date between NOW() + 1 interval day AND NOW(); //no records
select * from table where date between NOW() - 1 interval day AND NOW(); //works
Why does one call into the future work, but the same call into the past not work?...and if I reverse between parameters, the opposite behavior happens - does not work 24 hours into the future but does work 24 hours into the past.
======================
Adding #TimBiegeleisen explanation below here written out:
date = '2018-05-30' ;
select * from table where date between NOW() and NOW() + 1 interval day;
= date >= '2018-05-30' AND 'date <= 2018-05-31'; //true
select * from table where date between NOW() and NOW() - 1 interval day; records
= date >= '2018-05-30' AND 'date <= 2018-05-29'; //false
AND
select * from table where date between NOW() + 1 interval day AND NOW();
= date >= '2018-05-31' AND date <= '2018-05-30' //false
select * from table where date between NOW() - 1 interval day AND NOW();
= date >= '2018-05-29' and date <= '2018-05-30'; //true
The BETWEEN operator is interpreted a certain way:
WHERE date BETWEEN a AND b
means this:
WHERE date >= a AND date <= b
So the following two queries are equivalent:
select * from table where date between NOW() and NOW() - interval 1 day;
select * from table where date >= NOW() and date <= NOW() - interval 1 day;
Hopefully you can see that in your second query the WHERE condition can never be true, because a date cannot simutaneously be greater than or equal to now and less than now minus one at the same time.
simply put,
For SQL:
WHERE x between a and b
meaning
x >= a
and
x <= b
therefore, we have a <= x <= b or a <= b
PS: it's just about math :)

Get number of entries per multiple date intervals using single query

SELECT COUNT(*) FROM `table` WHERE `datetime` > SUBDATE(NOW(), INTERVAL 1 DAY)
This will get number of entries during last day. But is it possible to get number of entries for multiple intervals without having to send variation of this query multiple times (INTERVAL 1 DAY, INTERVAL 1 WEEK, INTERVAL 1 MONTH, ...)?
You need CASE WHEN expression to accomplish that.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
DATE(`datetime`) >= CURDATE() - INTERVAL 30 DAY
How to use CASE WHEN expression
Note: If your requirement is to get result of last day, last 7 days and last 30 days then go with this query.
EDIT:
If you have an index on datetime field then the above query will fail to use that index. Please use the query given below in order to utilize the index on datetime.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
`datetime` >= (NOW() - INTERVAL 30 DAY - INTERVAL HOUR(NOW()) HOUR - INTERVAL MINUTE(NOW()) MINUTE - INTERVAL SECOND(NOW()) SECOND)

Select between dates issues

I have this SQL:
$sql="SELECT *
FROM table
WHERE expiresdate >= Date(Now())
AND expiresdate <= Date_add(Date(Now()), INTERVAL 10 day)
ORDER BY expiresdate ASC";
it should basically show all rows in the database that are going to expire within 10 days time however, lets say the expiredate was 2013-03-06 - this row will not display on any day after the expiredate
does anyone have any ideas?
This should be what you need:
SELECT
*
FROM
`table`
WHERE
expiresdate <= CURDATE() + INTERVAL 10 DAY
ORDER BY
expiresdate ASC