I have a column name logdate which has dates in following format
2011-01-04 23:35:44.000
I want to select other columns in between 1st June 2011 till 30th June 2011 so the query should be
select * from abc where logdate = ?
You can use >= and <:
SELECT *
FROM abc
WHERE logdate >= '20110601' AND logdate < '20110701'
There are many ways to manipulate SQL datetimes and strings that represent SQL datetimes:
http://msdn.microsoft.com/en-us/library/ms186724(v=sql.105).aspx
A very straightforward way to do this would be to use >= < operators.
SELECT *
FROM abc
WHERE logdate >= '20110601'
AND logdate < '20110701'
The reason you want to use < July 1 as opposed to <= June 30 is that the string parsing on a date assumes it is midnight on that date, and it will exclude any values later than June 30 at 12 AM.
Assuming that LogDate is a DateTime column, you can use the following query to get the full range of the month:
WHERE logdate >= '2011-06-01' AND logdate < '2011-07-01'
Related
I have a table where it has some name and dateofbirth.
Refence data:
ABC, 1990-11-23
BCD, 1998-10-21
CDE, 1997-05-02
DEF, 2000-10-15
EFG, 1999-01-10
FGH, 1987-01-15
GHI, 1989-12-19
HIJ, 1986-12-09
I need a SQL query where I need to get the birthday celebration dates that is going to happen during the next 60 days ordered by celebration dates.
This is the query that I used till now.
SELECT *
FROM `friends`
WHERE ( DATE_FORMAT(`dob`, '%m%d') >= DATE_FORMAT(CURDATE(), '%m%d')
AND DATE_FORMAT(`dob`, '%m%d') <= DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 60 DAY), '%m%d')
ORDER BY DATE_FORMAT(`dob`, '%m%d');
It works ok if it runs during Jan to Oct. During November and December, the condition DATE_FORMAT(dob, '%m%d') <= DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 60 DAY), '%m%d') cannot apply. For example, the resulting comparison will be like 1209 < 0131 and fails.
The result that I expect to get when executed on Dec 2, 2022 is
HIJ, 1986-12-09
GHI, 1989-12-19
EFG, 1999-01-10
FGH, 1987-01-15
How do I do this in one single query?
The thread mentioned in the comment to your question uses things like adding 365.25 days to get this to work. I think this solution might be more reliable.
You can construct this years' birthday by extracting the month and day from the date of birth, and concatenating the current year to it using STR_TO_DATE.
Then you can check using a CASE statement if this years' birthday has already passed, in which case you add a year to that birthday, because that will be the next birthday for name. Then you can check if the result of that CASE statement is BETWEEN today and 60 days from now.
I used a CTE to make it clearer to read. DBfiddle here.
WITH cte as (
SELECT
-- First determine this years (year of current date) birthday
-- by constructing it from the current year, month of birth and day of birth
STR_TO_DATE(
CONCAT(YEAR(CURDATE()),'-', MONTH(dob), '-', DAY(dob)),
'%Y-%m-%d') AS this_years_birthday,
name,
dob
FROM friends
)
SELECT cte.name, cte.dob
FROM cte
WHERE
-- If the birthday is still in this year
-- Use this years' birthday
-- else add a year to this years' birthday
-- Then filter it to be between today and 60 days from now
CASE WHEN this_years_birthday >= CURDATE()
THEN this_years_birthday
ELSE DATE_ADD(this_years_birthday, INTERVAL 1 YEAR) END
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 60 DAY)
ORDER BY MONTH(cte.dob) DESC
name
dob
GHI
1989-12-19
HIJ
1986-12-09
EFG
1999-01-10
FGH
1987-01-15
According to this Kaggle exercise on Task 5 (Write the query):
https://www.kaggle.com/code/setthawutkulsrisuwan/exercise-as-with
I answered 2 ways:
Query with WHERE EXTRACT() to get year and month and the answer is
INCORRECT.:
WITH RelevantRides AS
(
SELECT EXTRACT(HOUR from trip_start_timestamp) as hour_of_day, trip_seconds, trip_miles
FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
WHERE EXTRACT(YEAR from trip_start_timestamp) = 2017 AND
EXTRACT(MONTH from trip_start_timestamp) BETWEEN 1 and 6 AND
trip_seconds > 0 AND
trip_miles > 0
)
SELECT hour_of_day,
COUNT(1) as num_trips,
3600 * SUM(trip_miles) / SUM(trip_seconds) as avg_mph
FROM RelevantRides
GROUP BY hour_of_day
ORDER BY hour_of_day
Query with the direct column name to get year and month and the answer is CORRECT.:
WITH RelevantRides AS
(
SELECT EXTRACT(HOUR from trip_start_timestamp) AS hour_of_day, trip_seconds, trip_miles
FROM `bigquery-public-data.chicago_taxi_trips.taxi_trips`
WHERE trip_start_timestamp > '2017-01-01' AND
trip_start_timestamp < '2017-07-01' AND
trip_seconds > 0 AND
trip_miles > 0
)
SELECT hour_of_day,
COUNT(1) as num_trips,
3600 * SUM(trip_miles) / SUM(trip_seconds) as avg_mph
FROM RelevantRides
GROUP BY hour_of_day
ORDER BY hour_of_day
The key differences are that first one is
WHERE EXTRACT(YEAR from trip_start_timestamp) = 2017
AND EXTRACT(MONTH from trip_start_timestamp) BETWEEN 1 and 6
, and the second is
WHERE trip_start_timestamp > '2017-01-01' AND
trip_start_timestamp < '2017-07-01'
.
In my opinion, they should result the same as querying with EXTRACT() shows year of 2017 and month of 1 to 6 as same as querying with the direct column name; however, results aren't the same.
Please explain the reasons behind those.
Thank you.
You're comparing constant dates to timestamps. Constant dates are actually timestamps looking like 2022-04-07 00:00:00.
So when you want to get all records in a date range January to June you need:
WHERE trip_start_timestamp >= '2017-01-01'
AND trip_start_timestamp < '2017-07-01'
In other words you want everything on or after midnight on the first day of the range and everything up to but not including midnight on the day after the last day. In mathematical notation you want the dates in the range [2017-01-01, 2017-07-01). The beginning of the range is closed and the end is open.
Your code like this gives a correct result.
WHERE EXTRACT(YEAR from trip_start_timestamp) = 2017
AND EXTRACT(MONTH from trip_start_timestamp) BETWEEN 1 and 6
But it can't exploit an index on your trip_start_timestamp column, so it won't be efficient in production.
I would like to select all records before 2014-03-22 date:
where date < 2014-03-22 // what I need
but below code doesn't see 2013 year's records :
SELECT * FROM `tractions` WHERE YEAR(date) <= 2014 AND MONTH(date) <= 3 and DAY(date) <= 22 and succ = 1
Is there anything wrong with:
SELECT * FROM tractions
WHERE date < '2014-03-22' -- place the date, correctly formatted, in quotes
Since this comparison doesn't use any functions, it will also allow you to use any indices setup on the date column.
I have a column called "s_timestamp."
How can I return all the records that have the current day in the timestamp?
For example,
s_timestamp
2012-12-27 1:00:00
2012-12-27 2:00:00
2012-12-26 0:00:01
2012-12-20 0:00:02
2012-12-21 0:00:03
I would like the following output:
2012-12-27 1:00:00
2012-12-27 2:00:00
Let me know if this is unclear.
just use CURDATE(). eg
SELECT *
FROM tableName
WHERE DATE(s_timestamp) = CURDATE()
DATE()
CURDATE()
This may be more efficient than casting the timestamps to DATE, especially if you have an index on the timestamp column (which you should have):
SELECT *
FROM tableName
WHERE s_timestamp >= CURDATE()
or, if you want to exclude any future dates:
SELECT *
FROM tableName
WHERE s_timestamp >= CURDATE()
AND s_timestamp < DATE_ADD(CURDATE(), INTERVAL 1 DAY)
This works because, when a DATETIME or a TIMESTAMP is compared with a DATE, the DATE is, in effect, interpreted as having a time part of 0:00:00.
I would like to rows that have only been entered in the last 1 day.
I have a date column which stores YYYY-MM-DD, and I allow the user to send a date that they want to look at in this format yyymmdd how can I use this data to limit it to the previous day only?
I would imagine it is something to do with the BETWEEN keyword but I cant figure it out.
SELECT * from TABLE_NAME WHERE ROW_DATE BETWEEN '2011-03-20' AND '2011-03-21'
This query:
SELECT *
FROM mytable
WHERE mydate >= STR_TO_DATE('110321', '%y%m%d') - INTERVAL 1 DAY
AND mydate < STR_TO_DATE('110321', '%y%m%d')
will return all records for Mar 20, 2011
From the MySQL manual (here):
SELECT something FROM tbl_name WHERE DATE_SUB(CURDATE(), INTERVAL 1 DAY) <= date_col;
SELECT * FROM YourTable WHERE date_column = DATE_ADD(CURDATE(), INTERVAL -1 DAY)
This returns all rows for today and yesterday.