Validate a date range within MySQL query - php

(This question may seem easy or kind of noobish, by that I pardon my ignorance.)
I used PDO query to use SELECT then fetch some values, it comes to a point that I need to fetch only some entries that within its start date and end date.
My database
+----------+-----------------+----------------------+--------------------+
| id (INT) | title (VARCHAR) | start_date (VARCHAR) | end_date (VARCHAR) |
+----------+-----------------+----------------------+--------------------+
| 1 | buddy | 2012-11-26 | 2012-11-30 |
| 2 | metro | 2012-12-05 | 2012-12-20 |
| 3 | justin | 2012-11-28 | 2012-12-01 |
+----------+-----------------+----------------------+--------------------+
My query is as follows:
$query = "SELECT title, start_date, end_date FROM debts WHERE start_date >= CURDATE() AND end_date >= CURDATE()";
What I want to achieve is whenever the start_date is today or greater but not exceeding the end_date it will be valid. This will return the row for id 1, however if I change the start_date to 2012-11-25, it will fail due to the first condition on AND. I'm really confuse on this since I am new to this, is there any built-in function to handle this kind of situation?

This is better:
SELECT title, start_date, end_date FROM debts
WHERE date(now()) BETWEEN start_date AND end_date

SELECT title, start_date, end_date FROM debts
WHERE start_date >= CURDATE() AND end_date <= CURDATE()

Related

Get the count of users before 90 days records from the e_date

Database table i have:
S.no | j_id |age | e_date |
-------------------------------------
1 | 1 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 1 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 2 |32 | 2018-05-09 |
-------------------------------------
-------------------------------------
1 | 2 |32 | 2018-04-16 |
-------------------------------------
-------------------------------------
1 | 1 |32 | 2018-09-16 |
-------------------------------------
-------------------------------------
1 | 3 |32 | 2018-04-16 |
------------------------------------
In my table I have expiry date I want to get the count of the result whose expiry date (90 days before) is equal to current date.
like I have expiry date 2018-05-09 and current date is 2018-02-2018 (90 days before date ) now i want to get to the count of the 90 days before result by query.
select * from yourtable
where datediff(CURDATE(), e_date) > 90
try to use datediff to get the different date count in day. Hope that this is what you want to get.
I like to keep the logic on the PHP side as much as possible, so I would probably calculate my expiry date in PHP and just add a simple where to the query. In Laravel that could look something like this:
$expireTreshold = Carbon::now()->addDays(90);
$expireCount = $myModel->where('e_date', '<=', $expireTreshold)->count();
For getting the current date, you can use CURDATE(), CURRENT_DATE(), and NOW() any one of these functions would get the current date. While the DATEDIFF() will get the difference between two periods (start date to end date).
If you only need to get the expiry dates that fit the 90 days condition use this :
SELECT e_date
FROM tableName
WHERE
e_date >= NOW()
AND datediff(e_date, NOW()) <= 90
In the query, you're scanning for future dates (from the current date and forward) and then get the differences, if the differences is less than or equal to 90 days, then it'll be selected.
if you need to show how many days left to each user:
SELECT sno, datediff(e_date, NOW())
FROM test
WHERE
e_date >= NOW()
AND datediff(e_date, NOW()) <= 90
It will work fine.
SELECT count(*) FROM table WHERE e_date < CURDATE() - INTERVAL 90 DAY;
OR
SELECT count(*) FROM table WHERE e_date < NOW() - INTERVAL 90 DAY;
cheers :)
Try this:
$your_date = "2018-01-01";
query = 'SELECT COUNT(*)
FROM thetable WHERE e_date =
DATE_ADD($your_date, INTERVAL 90 DAY)';

SQL count Query retrieving 0

i want to list the amount of views per object_id, between the current date and the date year ago.
So, i have this Query:
SELECT count(*) FROM event_logs WHERE object_id=252 AND object_type='product' AND event_type='view' AND event_date BETWEEN 2014-02-14 AND 2015-02-14 GROUP BY month(event_date)
And the following table:
event_id | user_id | objectd_id | object_type | event_type | event_date
1 | 1 | 252 | product | view | 2014-02-25 00:00:00
2 | 1 | 252 | product | view | 2015-02-12 19:36:05
3 | 1 | 252 | product | view | 2015-01-05 19:36:05
The problem is when i execute the query, show an amount of results of 0 (zero),
Could have i been doing wrong?
Please help and thank you all for your attention!
One problem is the event_date constants:
SELECT count(*)
FROM event_logs
WHERE object_id = 252 AND
object_type = 'product' AND
event_type = 'view' AND
event_date BETWEEN 2014-02-14 AND 2015-02-14
------------------------^ ---------^---^----------^ missing quotes
GROUP BY month(event_date);
Date constants should be in single quotes. Otherwise, these are treated as arithmetic -- 2014 - 2 - 14 = 1998, which is not really a valid date.
Also, if you want the total value, it is unclear why you are grouping by the month. You can use CURRENT_DATE and date arithmetic and not have to hardcode the dates:
SELECT count(*)
FROM event_logs
WHERE object_id = 252 AND
object_type = 'product' AND
event_type = 'view' AND
event_date <= CURRENT_DATE and
event_date > date_sub(CURRENT_DATE, interval -1 year);
Depending on the exact logic, you might want to change the <= to < or whatever -- depending on whether you want to include the end dates. Note: if event_date has a time component, then you might want to use date(event_date) to strip it off.
Change to this
BETWEEN '2014-02-14 00:00:00' AND '2015-02-14 23:59:59'

Mysql select record that should have today and tomorrow date

I want to select record that must have two or more entries but should have today and tomorrow date in table. I am saving date in table in date format.
SELECT `availibility`.*
FROM (`availibility`)
WHERE `property_id`= 8818
AND (availibility.unavailibility_date between CURDATE()
AND DATE_ADD(CURDATE(),INTERVAL 1 DAY))
I am using above query but this will true even one date (today or tomorrow) exists. I want to get such record that should have both dates
for example
+---------+----------------+------------+
| ID | property_id | Date |
+---------+----------------+------------+
| 369516 | 8818 | 2013-01-19 |
| 369517 | 8818 | 2013-01-18 |
| 369518 | 8818 | 2013-01-17 |
| 418021 | 8818 | 2013-08-27 |
| 418022 | 8818 | 2013-08-28 |
| 418022 | 8818 | 2013-08-29 |
| 418022 | 2001 | 2013-07-29 |
| 418022 | 2001 |2013-07-30 |
+---------+----------------+------------+
8818 property should come in record set because both date exists here
SELECT property_id
FROM yourtable
WHERE date IN (CURDATE(), CURDATE() + INTERVAL 1 DAY)
GROUP BY property_id
HAVING COUNT(DISTINCT date)=2
Please see fiddle here.
You can use:
NOW() + INTERVAL 1 DAY
If you are only interested in the date, not the date and time then you can use CURDATE instead of NOW:
CURDATE() + INTERVAL 1 DAY
your query should be
SELECT `availibility`.*
FROM (`availibility`)
WHERE `property_id`= 8818
AND (availibility.unavailibility_date between CURDATE()
AND CURDATE() + INTERVAL 1 DAY // change here
Use a JOIN to make sure the second record exists:
SELECT `availibility`.*
FROM `availibility`
JOIN `availibility` AS availibility_tomorrow ON availibility_tomorrow.property_id = availibility.property_id AND availibility_tomorrow.unavailibility_date = DATE_ADD(CURDATE (),INTERVAL 1 DAY))
WHERE `property_id`= 8818 AND availibility.unavailibility_date = CURDATE()
If i have understood this good...
SELECT `property_id`, count(*) as no
FROM (`availibility`)
WHERE `property_id`= 8818
AND (availibility.unavailibility_date=CURDATE()
OR availibility.unavailibility_date=DATE_ADD(CURDATE(),INTERVAL 1 DAY))
having no =2

Whats the best approach to get a whole month date?

I'm trying to make a website which gets some data from database and generate some statistics with this data.
The idea is to allow the user to pick a month and then only query data from that month. So, if the user picks January, query for data > 01/01/2011 and < 31/01/2011.
I thought about generating the starting data from the month and then add one month and subtract a day so I get the last day of the given month but I don't think that's the best approach and also don't know how to generate a full date from a given month.
Any ideas?
SQL centric way:
SELECT * FROM `foo` WHERE MONTH(`date`) = 3 AND YEAR(`date`) = 2011
Substitute the month and year numbers from your selection.
PHP centric way:
$month = 3;
$year = 2011;
$firstDay = "$year-$month-1";
$lastDay = "$year-$month-" . date('t', strtotime($firstDay));
$query = "SELECT * FROM `foo`
WHERE `date` >= '$firstDay'
AND `date` <= '$lastDay'";
Here is a lesson for you.
Most newbie programmers are looking for "the best", "most efficient" methods and stuff.
While they judge efficiency... by amount of the code! "Less code - more efficient!" - they think. And of course being wrong. Let's compare your "efficient" solution with "inefficient" one:
mysql> explain select * from Board where year(date) = 2011 and month(date) = 1;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | Board | ALL | NULL | NULL | NULL | NULL | 18113 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
mysql> explain select * from Board where date > '2010-12-31' and date < '2011-02-01';
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | Board | range | date | date | 9 | NULL | 325 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
Notice possible keys and rows parameters.
in the latter case a database going to get exact rows you need, in the former - its going to pick every row in the table, applying a function on the date and compare it with a constant.
Same goes for the solution from the poor guy who deleted his GOOD answer after your ignorant comment:
mysql> explain select * from Board where `date` > LAST_DAY(DATE_SUB('2011-01-15', INTERVAL 1 MONTH)) AND `date` < DATE_ADD(LAST_DAY('2011-01-15'), INTERVAL 1 DAY);
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | Board | range | date | date | 9 | NULL | 325 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
Nuff said.
Selecting records for the last month:
select `id`
from `orders`
where `created_at` > LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
AND `created_at` < DATE_ADD(LAST_DAY(CURDATE()), INTERVAL 1 DAY)
and for the previous month:
select `id`
from `orders`
where `created_at` > LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 2 MONTH))
AND `created_at` < DATE_ADD(LAST_DAY(CURDATE() - INTERVAL 1 MONTH), INTERVAL 1 DAY)
etc.
If you are saving your data as DateTimeStamp, simply add the condition to your query which would only return results from specific month of specific year. You could use LIKE clause for this.

Grab all items from MYSQL Table expired 1 day ago

MYSQL Table trial_list structure as follows...
id | product_id | expiry_date(date) | by_user | curr_datentime(timestamp)
we are able to extend any trial, and if we do that it simply another row with new expiry_date.
Now we would like to get rows got expired yesterday, we are currently using following sql query.....
Sample MYSQL DATASET
+----+-------------+-------------+-------------+----------+---------------------+
| id | product_id | comment | expiry_date | by_user | dnt |
+----+-------------+-------------+-------------+----------+---------------------+
| 2 | 50 | testing | 2011-02-18 | tester | 2011-02-17 23:36:12 |
+----+-------------+-------------+-------------+----------+---------------------+
| 3 | 50 | again | 2011-02-20 | tester | 2011-02-19 20:36:12 |
+----+-------------+-------------+-------------+----------+---------------------+
| 4 | 50 | extend | 2011-02-23 | tester | 2011-02-21 22:36:12 |
+----+-------------+-------------+-------------+----------+---------------------+
$sql = 'SELECT id, product_id, expiry_date, by_user, curr_datentime FROM trial_list WHERE expiry_date < CURDATE() ORDER BY expiry_date DESC';
We believe this is not correct as its getting all rows which date is older than yesterday not updated expiry_date, suppose we have given some user expiry date 1st feb 2011 and then we change again with 12th feb 2011, so it selects 1st feb 2011 entry. I think it makes sense.
What you have to do first is get the latest item per product_id. After that you can further filter it down to those which are expired. Something like:
SELECT a.* FROM
trial_list AS a
LEFT JOIN trial_list AS b ON a.product_id = b.product_id AND a.id < b.id
WHERE b.product_id IS NULL
AND a.expiry_date < curdate()
See http://dev.mysql.com/doc/refman/5.5/en/example-maximum-row.html
Try using NOW() instead of CURDATE(), you are comparing a Date to a Timestamp, NOW() will compare timestamps.

Categories