I'm trying to perform a query in SQL Server. I'm having trouble filtering the date. The output is always the same, the data doesn't get filter by date.
The date comes in the following format:
29-12-2020 16:38
31-12-2020 17:43
I tried to filter doing all the following but none worked out:
select
start_date
from table_1
where start_date between '01-01-2021 00:00:00' and '31-01-2021 00:00:00'
select
start_date
from table_1
where start_date between '01-01-2021 00:00' and '31-01-2021 00:00'
select
start_date
from table_1
where start_date between '01-01-2021' and '31-01-2021'
I also tried to cast it but I didn't have luck:
select
cast(start_date as date) as start_date
from table_1
where start_date between '2021-01-01' and '2021-01-31'
Can anyone help me?
Regards
You have a string. I strongly suggest making it a date/time of some sort. The following conversion works:
select convert(datetime, left(str, 10), 105) + convert(datetime, right(str, 5))
from (values ('29-12-2020 16:38')) v(str);
One operation is a computed column:
alter table table_1 start_date_dt as
( convert(datetime, left(start_date, 10), 105) + convert(datetime, right(start_date, 5)) )
Then you can use this value for your where clause. Or better yet. Fix the data! Don't store values in strings when there is an appropriate data type.
Related
I have a query (SQL Server 2012) that combines UNIX timestamps from two different tables into one column, which on its own works fine. The query needs to be sorted (descending) by the combined date column AND converted into a readable format.
If I attempt to sort after the date has been converted, it doesn't work as it is now a VARCHAR and returns:
05/02/2018
06/01/2017
07/03/2016
First I tried including a date conversion in the ORDER BY clause but that clearly doesn't work.
I then thought I could use a subquery to perform the sort then do the conversion in the main query (see below for what I currently have), but this is returning the error:
Invalid usage of the option NEXT in the FETCH statement.
I'm not using a fetch statement, so I'm wondering if there's something in my nesting that SQL Server doesn't like.
Any clues would be terrific.
-- Convert Epoch timestamp format to readable (and unsortable) dd/MM/yyyy format
SELECT CONVERT(VARCHAR(10), DATEADD(second, OuterTable.thedate-DATEDIFF(second, GETDATE(), GETUTCDATE()), CONVERT(DATETIME, '1970-01-01', 103)), 103) AS FinalDate
FROM (
-- Subquery only exists to do a proper date sort
SELECT thedate
FROM
(
SELECT
-- Determine which date to use
CASE WHEN x.dateX IS NOT NULL
THEN x.dateX
ELSE y.dateY
END AS thedate
-- Get date from first table
FROM (
SELECT id, dateX -- date is in Epoch format (BIGINT)
FROM tableX
) AS x
-- Get date from second table
JOIN (
SELECT id, dateY -- date is in Epoch format (BIGINT)
FROM tableY
) AS y
ON x.id = y.id
)
-- Perform sort while date is still in epoch format
ORDER BY thedate DESC
) AS OuterTable
IMO this should work for you:
SELECT CONVERT(VARCHAR(10), DATEADD(second, COALESCE(x.dateX, y.dateY) - DATEDIFF(second, GETDATE(), GETUTCDATE()), CONVERT(DATETIME, '1970-01-01', 103)), 103) AS FinalDate
FROM tableX AS x
INNER JOIN tableY AS y
ON x.id = y.id
ORDER BY COALESCE(x.dateX, y.dateY) DESC;
Not sure when copy/paste the CONVERT function. Is it so complicated to convert epoch to dd/MM/yyyy in MSSQL?
i have dates stored as chars in db (i know, but its not my db nor my idea..).
One of the dates is stored as MMYYYY (012016,022016...) and the second one is stored as YYYYMMDD (20160101,20160202...).
Is there a way to compare those dates? I need to take one date and select all of the second dates which are at least one year older then the first one...
Thank you for any help !
So for example i have Date1 field with values : 012014,012015,012016
and Date2 field with value: 20141005
And i need only Date1 which is at least one year older then Date2 so in this case it will return only 012016
I make two ctes to show how to work it out. I assume MMYYYY are stored as nvarchar or varchar and YYYYMMDD are the same type. If not - you will need one/few conversions on YYYYMMDD field.
;WITH cte AS (
SELECT '012016' as MMYYYY
UNION ALL
SELECT '022016'
), cte2 AS (
SELECT '20160101' AS YYYYMMDD
UNION ALL
SELECT '20160202'
)
SELECT *
FROM cte c
INNER JOIN cte2 c2
ON YYYYMMDD LIKE RIGHT(MMYYYY,4)+LEFT(MMYYYY,2) +'%'
Output:
MMYYYY YYYYMMDD
012016 20160101
022016 20160202
EDIT:
To find out differences in years use this:
DATEDIFF(year,CAST(YYYYMMDD as date), CAST(RIGHT(MMYYYY,4)+LEFT(MMYYYY,2)+'01' as date))
You can convert both fields into type DATE, then compare them.
For MMYYYY, you can use the function DATEFROMPARTS() to build a date. For example, convert 012014 into date:
-- DATEFROMPARTS(year, month, day)
DATEFROMPARTS(RIGHT('012014', 4), LEFT('012014', 2), 1)
For YYYYMMDD, it is easier, because this is the format ISO with Time Style 112. You can use the CONVERT() function to do the conversion :
CONVERT(DATE, '20141005', 112)
And here's how the final query looks like :
WITH casted AS (
SELECT
DATEFROMPARTS(RIGHT(date1, 4), LEFT(date1, 2), 1) AS d1,
CONVERT(DATE, date2, 112) AS d2,
-- ...
FROM yourTable
)
SELECT *
FROM casted
WHERE d1 <= DATEADD(YEAR, -1, d2)
try this
column1 is stored MMYYYY format and column2 is stored YYYYMMDD.
where column1= case when datepart(month,taskDuedate)>9 then convert(varchar,datepart(month,taskDuedate))else '0'+convert(varchar,datepart(month,taskDuedate))end+convert(varchar,datepart(year,taskDueDate))
I have some SQL below which is programmatically generated:
INSERT INTO TABLE (COMID, NAME, DATE)
SELECT DISTINCT 'COM001', 'John', '01-Jan-4501 00:00:00'
How can i amend this so that if it finds the date time of : 01-Jan-4501 00:00:00 then it replaces it with todays date?
You probably want to avoid some wrong or irrelevant values.
SELECT
'COM001',
'John',
case
when cast('01-Jan-4501 00:00:00' as date) > cast('01-Jan-2100 00:00:00' as date)
then cast(getdate() as varchar(30))
else '01-Jan-4501 00:00:00'
end
Another way is to create a trigger on that table that automatically makes the date field correction.
SELECT DISTINCT 'COM001', 'John',
case when date = '01-Jan-4501 00:00:00' then convert(date,getdate()) end
I have a view I am creating and I want to group by an extracted date from a column that has a date and time. This is where I am....
SELECT
ClockCode AS MOnum, SUM(Actual_Hrs) AS Runtothours, TStamp
FROM
dbo.Raw_Booking
WHERE
(Actual_Hrs > 0) AND (ClockCode LIKE 'MO%')
AND (TStamp > CONVERT(DATETIME, '2013-01-01 00:00:00', 102))
GROUP BY
ClockCode, TStamp
so while I have it grouped by the TStamp column there is a record for each one based on the time... I am looking to get a total amount of run time for each order by date.
The TStamp column is formatted as:
2013-01-02 08:18:47.000
If you can change your schema, store it as a date to begin with. Otherwise, change your group by clause to something similar to...
GROUP BY CAST(TStamp AS DATE)
EDIT: Forgot you were in SQL 2005. You can still do something like the following, but keep in mind this should be considered an ugly, short-term, workaround. All the comments in this thread about redesigning are completely valid and should be pursued...
GROUP BY SUBSTRING(TStamp, 0, 11)
SELECT ClockCode AS MOnum
, SUM(Actual_Hrs) AS Runtothours
, TStampDate
FROM dbo.Raw_Booking
CROSS APPLY (
SELECT CONVERT(datetime, TStamp, 102) AS TStampDateTime
) AS CA1
CROSS APPLY (
SELECT DATEADD(day, DATEDIFF(day, 0, TStampDateTime), 0) AS TStampDate
) AS CA2
WHERE Actual_Hrs > 0
AND ClockCode LIKE 'MO%'
AND TStampDateTime > CONVERT(DATETIME, '2013-01-01 00:00:00', 102))
GROUP BY ClockCode
,TStampDate
Is there a way to use the Now() function in SQL to select values with today's date?
I was under the impression Now() would contain the time as well as date, but today's date would have the time set to 00:00:00 and therefore this would never match?
OK, lets do this properly. Select dates matching today, using indexes if available, with all the different date/time types present.
The principle here is the same in each case. We grab rows where the date column is on or after the most recent midnight (today's date with time 00:00:00), and before the next midnight (tomorrow's date with time 00:00:00, but excluding anything with that exact value).
For pure date types, we can do a simple comparison with today's date.
To keep things nice and fast, we're explicitly avoiding doing any manipulation on the dates stored in the DB (the LHS of the where clause in all the examples below). This would potentially trigger a full table scan as the date would have to be computed for every comparison. (This behaviour appears to vary by DBMS, YMMV).
MS SQL Server: (SQL Fiddle | db<>fiddle)
First, using DATE
select * from dates
where dte = CAST(CURRENT_TIMESTAMP AS DATE)
;
Now with DATETIME:
select * from datetimes
where dtm >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
Lastly with DATETIME2:
select * from datetimes2
where dtm2 >= CAST(CURRENT_TIMESTAMP AS DATE)
and dtm2 < DATEADD(DD, 1, CAST(CURRENT_TIMESTAMP AS DATE))
;
MySQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = cast(now() as date)
;
Using DATETIME:
select * from datetimes
where dtm >= cast((now()) as date)
and dtm < cast((now() + interval 1 day) as date)
;
PostgreSQL: (SQL Fiddle | db<>fiddle)
Using DATE:
select * from dates
where dte = current_date
;
Using TIMESTAMP WITHOUT TIME ZONE:
select * from timestamps
where ts >= 'today'
and ts < 'tomorrow'
;
Oracle: (SQL Fiddle)
Using DATE:
select to_char(dte, 'YYYY-MM-DD HH24:MI:SS') dte
from dates
where dte >= trunc(current_date)
and dte < trunc(current_date) + 1
;
Using TIMESTAMP:
select to_char(ts, 'YYYY-MM-DD HH24:MI:SS') ts
from timestamps
where ts >= trunc(current_date)
and ts < trunc(current_date) + 1
;
SQLite: (SQL Fiddle)
Using date strings:
select * from dates
where dte = (select date('now'))
;
Using date and time strings:
select dtm from datetimes
where dtm >= datetime(date('now'))
and dtm < datetime(date('now', '+1 day'))
;
Using unix timestamps:
select datetime(dtm, 'unixepoch', 'localtime') from datetimes
where dtm >= strftime('%s', date('now'))
and dtm < strftime('%s', date('now', '+1 day'))
;
Backup of SQL Fiddle code
There is no native Now() function in SQL Server so you should use:
select GETDATE() --2012-05-01 10:14:13.403
you can get day, month and year separately by doing:
select DAY(getdate()) --1
select month(getdate()) --5
select year(getdate()) --2012
if you are on sql server 2008, there is the DATE date time which has only the date part, not the time:
select cast (GETDATE() as DATE) --2012-05-01
Not sure what your asking!
However
SELECT GETDATE()
Will get you the current date and time
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
Will get you just the date with time set to 00:00:00
Just zero off the time element of the date. e.g.
SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
I've used GetDate as that's an MSSQL function, as you've tagged, but Now() is probably MySQL or you're using the ODBC function call, still should work if you just replace one with the other.
Not sure exactly what you're trying to do, but it sounds like GETDATE() is what you're after. GETDATE() returns a datetime, but if you're not interested in the time component then you can cast to a date.
SELECT GETDATE()
SELECT CAST(GETDATE() AS DATE)
Building on the previous answers, please note an important point, you also need to manipulate your table column to ensure it does not contain the time fragment of the datetime datatype.
Below is a small sample script demonstrating the above:
select getdate()
--2012-05-01 12:06:51.413
select cast(getdate() as date)
--2012-05-01
--we're using sysobjects for the example
create table test (id int)
select * from sysobjects where cast(crdate as date) = cast(getdate() as date)
--resultset contains only objects created today
drop table test
I hope this helps.
EDIT:
Following #dwurf comment (thanks) about the effect the above example may have on performance, I would like to suggest the following instead.
We create a date range between today at midnight (start of day) and the last millisecond of the day (SQL server count up to .997, that's why I'm reducing 3 milliseconds). In this manner we avoid manipulating the left side and avoid the performance impact.
select getdate()
--2012-05-01 12:06:51.413
select dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--2012-05-01 23:59:59.997
select cast(getdate() as date)
--2012-05-01
create table test (id int)
select * from sysobjects where crdate between cast(getdate() as date) and dateadd(millisecond, -3, cast(cast(getdate()+1 as date) as datetime))
--resultset contains only objects created today
drop table test
If you have a table with just a stored date (no time) and want to get those by "now", then you can do this:
SELECT * FROM tbl WHERE DATEDIFF(d, yourdate, GETDATE())=0
This results in rows which day difference is 0 (so today).
For me the query that is working, if I want to compare with DrawDate for example is:
CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
This is comparing results with today's date.
or the whole query:
SELECT TOP (1000) *
FROM test
where DrawName != 'NULL' and CAST(DrawDate AS DATE) = CAST (GETDATE() as DATE)
order by id desc
You can try this sql code;
SELECT [column_1], [column_1], ...
FROM (your_table)
where date_format(record_date, '%e%c%Y') = date_format(now(), '%e%c%Y')
You can try:
WHERE created_date BETWEEN CURRENT_TIMESTAMP-180 AND CURRENT_TIMESTAMP
This worked for me:
SELECT * FROM table where date(column_date) = curdate()