Between Operator - Mysqli [duplicate] - php

I have saved the dates of a user's registration as a datetime, so that's for instance 2011-12-06 10:45:36. I have run this query and I expected this item - 2011-12-06 10:45:36 - will be selected:
SELECT `users`.* FROM `users` WHERE created_at >= '2011-12-01' AND
created_at <= '2011-12-06'
But is not. Exist any elegant way, how to select this item? As a first idea that I got was like 2011-12-06 + 1, but this doesn't looks very nice.

Your problem is that the short version of dates uses midnight as the default. So your query is actually:
SELECT users.* FROM users
WHERE created_at >= '2011-12-01 00:00:00'
AND created_at <= '2011-12-06 00:00:00'
This is why you aren't seeing the record for 10:45.
Change it to:
SELECT users.* FROM users
WHERE created_at >= '2011-12-01'
AND created_at <= '2011-12-07'
You can also use:
SELECT users.* from users
WHERE created_at >= '2011-12-01'
AND created_at <= date_add('2011-12-01', INTERVAL 7 DAY)
Which will select all users in the same interval you are looking for.
You might also find the BETWEEN operator more readable:
SELECT users.* from users
WHERE created_at BETWEEN('2011-12-01', date_add('2011-12-01', INTERVAL 7 DAY));

SELECT users.* FROM users WHERE created_at BETWEEN '2011-12-01' AND '2011-12-07';

You need to use '2011-12-07' as the end point as a date without a time default to time 00:00:00.
So what you have actually written is interpreted as:
SELECT users.*
FROM users
WHERE created_at >= '2011-12-01 00:00:00'
AND created_at <= '2011-12-06 00:00:00'
And your time stamp is: 2011-12-06 10:45:36 which is not between those points.
Change this too:
SELECT users.*
FROM users
WHERE created_at >= '2011-12-01' -- Implied 00:00:00
AND created_at < '2011-12-07' -- Implied 00:00:00 and smaller than
-- thus any time on 06

Another alternative is to use DATE() function on the left hand operand as shown below
SELECT users.* FROM users WHERE DATE(created_at) BETWEEN '2011-12-01' AND '2011-12-06'

Have you tried before and after rather than >= and <=? Also, is this a date or a timestamp?

Searching for created_at <= '2011-12-06' will search for any records that where created at or before midnight on 2011-12-06
. You want to search for created_at < '2011-12-07'.

Maybe use in between better. It worked for me to get range then filter it

You can use MySQL DATE function like below
For instance, if you want results between 2017-09-05 till 2017-09-09
SELECT DATE(timestamp_field) as date FROM stocks_annc WHERE DATE(timestamp_field) >= '2017-09-05' AND DATE(timestamp_field) <= '2017-09-09'
Make sure to wrap the dates within single quotation ''
Edit:
A better solution would be this. It would make sure that it uses the index if any exists.
select date(timestamp_field) as date from stocks_annc where time_stamp_field >= '2022-01-01 00:00:00' and time_stamp_field <= '2022-01-10 00:00:00'
Hope this helps.

Related

Select count for each day in a month

I have a sms tracker database with a date column in the format 02/25/2018 04:12:52 pm. I want to count the no of sms sent each day to display it in bar chart.
I could only count sms sent by a user using this query "SELECT count(*) as user_count from table where username = 'CTC01'". How can i get an array of count for each day in a particular month
Since OP's date_column is VARCHAR type. We use STR_TO_DATE function:
SELECT DATE(STR_TO_DATE(date_column, "%m/%d/%Y %r")), COUNT(*)
FROM table
GROUP BY DATE(STR_TO_DATE(date_column, "%m/%d/%Y %r"));
Use DATE function, to convert a datetime expression to a date. Then use GROUP BY to get COUNT datewise.
In case, you want to get data for a specific user (eg: CTC01) and datewise. You can do the following:
SELECT DATE(STR_TO_DATE(date_column, "%m/%d/%Y %r")), COUNT(*)
FROM table
WHERE username = 'CTC01'
GROUP BY DATE(STR_TO_DATE(date_column, "%m/%d/%Y %r"));
I see your date format is 'm/d/Y H:i:s'. So, to get the total for each day in a month, you have to do a comparison against the least time in that month and the highest time in that month. So, the query for February 2018 would be:
SELECT DATE(date_column), COUNT(*)
FROM jobs
where created_on >= '02/01/2018 00:00:00' and created_on < '03/01/2018 00:00:00'
GROUP BY DATE(date_column);
To get for a particular user, simply append a where clause to the query above like so:
SELECT DATE(date_column), COUNT(*)
FROM jobs
where created_on >= '02/01/2018 00:00:00' and created_on < '03/01/2018 00:00:00' and username = 'CTC01'
GROUP BY DATE(date_column);
EDIT
Since your date column is varchar, you first have to convert it to datetime. So run this query instead:
SELECT DATE(DATE_FORMAT(STR_TO_DATE(date_column, '%c/%e/%Y %H:%i'), '%Y-%m-%d %H:%m:%s')) as Date, COUNT(*)
FROM jobs
where created_on >= '02/01/2018 00:00:00' and created_on < '03/01/2018 00:00:00'
GROUP BY DATE(DATE_FORMAT(STR_TO_DATE(date_column, '%c/%e/%Y %H:%i'), '%Y-%m-%d %H:%m:%s'));

Sql Query to find data only from last hour

I Have An table As Follow
I need Data Only From Last Hour. Following query i tried using Reference.
SELECT * FROM `user_otp`
WHERE `date` = '$todate'
AND datetime > DATEADD(HOUR, -1, GETDATE())
I Dont Know This But I tried Using This Refferance
But It Not Work For Me .
So Any Help Would be useful.
DATEADD and GETDATE() exist in SQL Server.
In MySQL, your conditions should be:
WHERE `datetime` > DATE_ADD(NOW(), INTERVAL -1 HOUR)
While date = '$todate' condition is redundant and should be removed.
Here's a documentation in MySQL DateTime.
Use DATE_SUB and NOW() functions in query
SELECT count(*) as lasthour_count
FROM user_otp
WHERE datetime >= DATE_SUB(NOW(),INTERVAL 1 HOUR);
Hi you can use DATE_SUB function for fetch last one hour data. I edited your code below -
SELECT * FROM `user_otp`
WHERE `date` = '$todate'
AND datetime >= DATE_SUB(NOW(),INTERVAL 1 HOUR);
datetime>=DATE_ADD(NOW(), INTERVAL -1 HOUR);
datetime>= DATE_sub(NOW(), INTERVAL 1 HOUR);
These are the two options you can use

MySQL BETWEEN DATE RANGE

I have a scenario where I need to pull up delivery dates based on a table below (Example)
job_id | delivery_date
1 | 2013-01-12
2 | 2013-01-25
3 | 2013-02-15
What I'm trying to do is show the user all the delivery dates that start with the earliest (in this case it would be 2013-01-12) and add an another 21 days to that. Basically, the output I would expect it to show of course, the earliest date being the starting date 2013-01-12 and 2013-01-25. The dates past the February date are of no importance since they're not in my 21 date range. If it were a 5 day range, for example, then of course 2013-01-25 would not be included and only the earliest date would appear.
Here is main SQL clause I have which only shows jobs starting this year forward:
SELECT date, delivery_date
FROM `job_sheet`
WHERE print_status IS NULL
AND job_sheet.date>'2013-01-01'
Is it possible to accomplish this with 1 SQL query, or must I go with a mix of PHP as well?
You can use the following:
select *
from job_sheet
where print_status IS NULL
and delivery_date >= (select min(delivery_date)
from job_sheet)
and delivery_date <= (select date_add(min(delivery_date), interval 21 day)
from job_sheet)
See SQL Fiddle with Demo
If you are worried about the dates not being correct, if you use a query then it might be best to pass in the start date to your query, then add 21 days to get the end date. Similar to this:
set #a='2013-01-01';
select *
from job_sheet
where delivery_date >= #a
and delivery_date <= date_add(#a, interval 21 day)
See SQL Fiddle with Demo
SELECT date,
delivery_date
FROM job_sheet
WHERE print_status IS NULL
AND job_sheet.date BETWEEN (SELECT MIN(date) FROM job_sheet) AND
(SELECT MIN(date) FROM job_sheet) + INTERVAL 21 DAY
SELECT j.job_id
, j.delivery_date
FROM `job_sheet` j
JOIN ( SELECT MIN(d.delivery_date) AS earliest_date
FROM `job_sheet` d
WHERE d.delivery_date >= '2013-01-01'
) e
ON j.delivery_date >= e.earliest_date
AND j.delivery_date < DATE_ADD(e.earliest_date, INTERVAL 22 DAY)
AND j.print_status IS NULL
ORDER BY j.delivery_date
(The original query has a predicate on job_sheet.date; the query above references the d.delivery_date... change that if it is supposed to be referencing the date column instaed.)
If the intent is to only show delivery_date values from today forward, then change the literal '2013-01-01' to an expression that returns the current date, e.g. DATE(NOW())

Assistance with MySQL query & timestamps

I am trying to create a query which returns offers for all rows that belong to a club_id that are within a start_date & end_date, however the query should also return results for any that match the club_id AND the end_date is 0 - any ideas of how to do this?
My current query is below...
SELECT
* ,
UNIX_TIMESTAMP( start_date ) AS start_dateStamp,
UNIX_TIMESTAMP( end_date ) AS end_dateStamp
FROM
(`offers`)
WHERE
UNIX_TIMESTAMP( `start_date` ) <1329308797
AND
UNIX_TIMESTAMP( `end_date` ) >1329308797
AND
`club_id` =23
SELECT
`offers`.* ,
UNIX_TIMESTAMP( start_date ) AS start_dateStamp,
UNIX_TIMESTAMP( end_date ) AS end_dateStamp
FROM `offers`
WHERE `club_id` =23
AND (
(
`start_date`<FROM_UNIXTIME(1329308797)
AND `end_date`>FROM_UNIXTIME(1329308797)
)
OR `end_date`=FROM_UNIXTIME(0)
)
Please note, that I moved the convertion from unix-timestamp to MySQL-date from the field to the constant - this way it has to be converted only once, and not for all rows. Additionally this way an index can be used.
Edit
With "date zero" not being Unix-Zero but MySQL-Zeor the last line should be
OR `end_date`='0000-00-00'
additionally, if the data type of start_date and end_date is not DATETIME but DATE you need
DATE(FROM_UNIXTIME(...))
instead of
FROM_UNIXTIME(...)
you didn't specify if end_date = 0 also reqires start_date > $timestamp, so I assumed start_date still has to meet its criteria.
SELECT
please_name,
the_columns,
you_want_to_select_seperately,
for_reasons,
UNIX_TIMESTAMP(start_date) AS start_dateStamp,
UNIX_TIMESTAMP(end_date) AS end_dateStamp
FROM `offers`
WHERE `club_id` = 23
AND `start_date`) < UNIX_TIMESTAMP(1329308797)
AND (`end_date` > UNIX_TIMESTAMP(1329308797) OR `end_date` = "0000-00-00")
Some notes on your SQL:
don't use * unless you have reasons. which, judging from your original question, you really really don't
try to format your code so it's readable
sort your conditions so the condition selecting the fewest records (read: has the highest specificity) comes first. This has become more a mental thing than hinting the MySQL optimizer, it's still a convention I'd stick to
if you compare (date) ranges, consider using col BETWEEN min_val and max_val (boundaries are inclusive)
don't use functions in the WHERE and GROUP BY clause. MySQL cannot cache/index these and must thus run the value of every row through that function. UNIX_TIMESTAMP() has a friend named FROM_UNIXTIME() - doing pretty much the exact opposite. This is nothing you can't do yourself in PHP with date(), though.
consider setting fields to NULL if they have an unknown value. You either have a date (2012-02-15) or you don't (NULL). That would allow your query to simply check OR end_date IS NULL
Is this what you want?
SELECT *
, UNIX_TIMESTAMP(start_date) AS start_dateStamp
, UNIX_TIMESTAMP(end_date) AS end_dateStamp
FROM
`offers`
WHERE
(UNIX_TIMESTAMP(`start_date`) < 1329308797 AND UNIX_TIMESTAMP(`end_date`) > 1329308797)
OR
(`club_id` = 23 AND `end_date` = '0000-00-00 00:00:00')

SQL and date comparison

I have a sql statement, i select a few items, but I need to make sure that the date i have saved is greater then the current date.
SELECT * FROM table WHERE column_date > current_date
How do I make the code over, working?
Column date is saved like this 0000-00-00 00:00:00 (usual save, in other words).
This is what I try to achieve: AND time > current_date OR time == NULL But it ain't working. The time column is currently 0000-00-00 00:00:00 which is NULL, right?
Or how can I do, it must be greater than or equal to 0000-00-00 00:00:00
If you are using MySQL, NOW() should do the trick.
SELECT * FROM table WHERE column_date > NOW()
If you want to eliminate the time value and just compare to date value, following could be used:
SELECT * FROM table WHERE column_date > CURDATE()
You could use the Mysql Function NOW():
SELECT * FROM table WHERE column_date > NOW()
As per this documentation article, 0000-00-00 is a "dummy date" that can be used instead of NULL, which means 0000-00-00 itself is not NULL.
Given that 0000-00-00 cannot be greater than any other date, you should use either a condition with OR:
SELECT * FROM table WHERE column_date > NOW() OR column_date = '0000-00-00'
or a union:
SELECT * FROM table WHERE column_date > NOW()
UNION ALL
SELECT * FROM table WHERE column_date = '0000-00-00'
Alternatively you could use a construct like this:
SELECT *
FROM table
WHERE IFNULL(NULLIF(column_name, '0000-00-00'), '9999-12-31') > NOW()
But that would probably prohibit the query from taking advantage of the index on column_date, if any.

Categories