WHERE clause with 6 months condition - sql

I am working on trying to list every item that hasn't changed in the last month but when I run this query:
select * from AGLT.LTB0040 WHERE wdate> current_date - 6 MONTHS
I get an error message saying that the value is not valid. I have checked the dates listed in the field and they are 20160101. Any idea on where I have gone wrong?

If date column is a representation of a date make a string or numeric comparison.
If the date is a 8 char field
WHERE wdate >= varchar_format(current
timestamp- 6 months,'YYYYMMDD')
If the date is 8,0 field
WHERE wdate >= cast( varchar_format(current
timestamp- 6 months,'YYYYMMDD') as decimal(8,0))

Related

Redshift can't convert a string to a date, tried multiple functions

I have a table with a field called ADATE, it is a VARCHAR(16) and the values are like so: 2019-10-22-09:00.
I am trying to convert this do a DATE type but cannot get this to work.
I have tried:
1
TO_DATE(ADATE, 'YYYY-MM-DD')
Can't cast database type date to string
2
TO_DATE(LEFT(ADATE, 10), 'YYYY-MM-DD')
Can't cast database type date to string
3
TO_DATE(TRUNC(ADATE), 'YYYY-MM-DD')
XX000: Invalid digit, Value '-', Pos 4, Type: Decimal
4
CAST(ADATE AS DATE)
Error converting text to date
5
CAST(LEFT(ADATE, 10) AS DATE)
Error converting text to date
6
CAST(TRUNC(ADATE) AS DATE)
Error converting numeric to date
The issue was the data containing blanks (not Nulls) so the error was around them.
I resolved this by using the following code:
TO_DATE(LEFT(CASE WHEN adate = '' THEN NULL ELSE adate END, 10), 'YYYY-MM-DD') adate
Clearly, you have bad date string values -- which is why the value should be stored as a date to begin with.
I don't think Redshift has a way of validating the date before attempting the comparison, or of avoiding an error. But you can use case and regular expressions to see if the value is reasonable. This might help:
(case when left(adate, 10) ~ '^(19|20)[0-9][0-9]-[0-1][0-9]-[0-3][0-9]$'
then to_date(left(adate, 10), 'YYYY-MM-DD')
end)
This is not precise . . . you can make it more complex so month 19 is not permitted (for instance), but it is likely to catch the errors.

Convert varchar(20) into date format Teradata SQL

I have a column months which is a varchar(20) . How can I convert it to a date format . I did try this
select CAST(month as DATE FORMAT'dd.mm.yyyy') from TABLE_123
For which I get an error invalid date supplied for TABLE_123.
Thank you.
month
12
11
1
3
6
6
select CAST(month as DATE FORMAT'dd.mm.yyyy') from TABLE_123
According to my understanding the format of input string should be same as 'dd.mm.yyyy' while casting as date and your input sample shows that it does not satisfy that necessary condition.
Please correct me if I'm wrong.

How to deal with a date stored as a string in an int field in Teradata?

I've got a table in Teradata that stores a date in an 8 character INT field in the following form "YYYYMMDD", so for today it would store "20180308". If I try to CAST it as a date like this:
CAST(date_field AS DATE FORMAT 'YYYY-MM-DD')
It transforms the date to some future date in the year 3450 or something.
I think it's an error that this data isn't either stored as a date object. Is there anyway to overcome this glitch? I don't have access to change this unfortunately.
Thanks
It's not an 8 character integer, it's an 8 digit integer.
Teradata stores dates using
(year - 1900) * 10000
+ (month * 100)
+ day
This results in 1180308 for today and 20180308 will return 3918-03-08
To cast it to a date you need to use
cast(intdate-19000000 as date)
select cast('20180308' as date format 'yyyymmdd') ;

Find data with specific date and month only

I am trying to find a data with specific where clause of date and month but I am receiving an error can anyone help me with this?
select *
from my_data
where date BETWEEN '11-20' AND '12-15'
MS SQL Server Management Studio
I am receving an error
Conversion failed when converting date and/or time from character string
Most databases support functions to extract components of dates. So, one way of doing what you want is to convert the values to numbers and make a comparison like this:
where month(date) * 100 + day(date) between 1120 and 1215
The functions for extracting date parts differ by database, so your database might have somewhat different methods for doing this.
The conversion is failing because you are not specifying a year. If you were to specify '11-20-2015' your query would work just insert whatever year you need.
SELECT *
FROM my_data
WHERE date BETWEEN '11-20-2015' AND '12-15-2015'
Alternatively if you wanted data from that range of dates for multiple years I would use a while loop to insert information in a # table then read from that table, depending on the amount of data this could be quick or sloooowww here is an example.
DECLARE #mindatestart date, #mindateend date, #maxdatestart date
SET #mindatestart = '11-20-2010'
SET #mindateend = '12-15-2010'
SET #maxdatestart = '11-20-2015'
SELECT top 0 *, year = ' '
INTO #mydata
FROM my_data
WHILE #mindatestart < #maxdatestart
BEGIN
INSERT INTO #mydata
SELECT *, YEAR(#mindatestart)
FROM my_data
where date between #mindatestart and #mindateend
SET #mindatestart = DATEADD(Year, 1, #mindatestart)
SET #mindateend = DATEADD(Year, 1, #mindateend)
END
This will loop and insert the data from 2010-2015 for those date ranges and add a extra column on the end so you can call the data and order by year if you want like this
SELECT * FROM #mydata order by YEAR
Hopefully some part of this helps!
FROM THE COMMENT BELOW
SELECT *
FROM my_data
WHERE DAY(RIGHT(date, 5)) between DAY(11-20) and DAY(12-15)
The reason '11-20' doesn't work is because its a character string which is why you have to input it between ' ' What the Month() function does is take whatever you put between the () and convert it to an integer. Which is why you're not getting anything back using the method in the first answer, the '-Year' from the table date field is being added into the numeric value where your value is just being converted from 11-20 you can see by using these queries
SELECT MONTH(11-20) --Returns 12
SELECT MONTH(11-20-2015) -- Returns 6
SELECT MONTH(11-20-2014) -- Returns 6
Using RIGHT(Date, 5) you only get Month-day, then you date the day value of that so DAY(RIGHT(DATE, 5) and you should get something that in theory should fall within those date ranges despite the year. However I'm not sure how accurate the data will be, and its a lot of work just to not add an additional 8 characters in your original query.
Since you only care about month and day, but not year, you need to use DATEPART to split up the date. Try this:
select *
from my_data
WHERE 1=1
AND (DATEPART(m, date) >= 11 AND DATEPART(d,date) >= 20)
AND (DATEPART(m, date) <= 12 AND DATEPART(d,date) <= 15)

Concatenating date and time fields

I have a table invoices with this fields:
invDate -> a date field
invTime -> a time field
I need to do querys like
SELECT top 10 * from invoices WHERE DATETIME(invDate+invTime)
BETWEEN DATETIME('2013-12-17 17:58') AND DATETIME()
or something like that. I don't know how to concatenate the invDate and invTime to create a datetime field. The only thing that i could do is this horribly thing:
DATETIME( YEAR(invDate), MONTH(invDate), DAY(invDate), 17, 52 ) AS MyDatetime
Couldn't even get hour and time with hour(invTime) and minute(invTime):
DATETIME( YEAR(invDate), MONTH(invDate), DAY(invDate),
HOUR(invTime), MINUTE(invTime) ) AS MyDatetime
I'm doing the querys throught the VFP Odbc Driver via PHP.
You were pretty close. If the value coming from PHP is not of a date/time, how could VFP interpret it properly. VFP also has a function CTOT() (character to time), and expects it in the format of 'yyyy-mm-ddThh:MM:ss??'
yyyy = 4 digit year
mm = 1 OR 2 digit month
dd = 1 OR 2 digit day
T -- literally the letter "T"
hh = 1 OR 2 digit hour (but typical is 2 anyhow)
MM = 1 or 2 digit minute (but typical is 2)
ss = 1 or 2 digit for seconds -- not required
?? = "AM" or "PM" if you wanted to explicitly provide that vs 24 hour clock
The MM and ss are optional, so if you finished with "T1" would be 1:00:00am
Now, to finish your query.
WHERE DATETIME(invDate+invTime)
BETWEEN DATETIME('2013-12-17 17:58') AND DATETIME()
Since this appears to be querying all invoices between a given date/time and NOW (via DateTime()), you don't even need between, you can do
WHERE YourTable.Column > CTOT( '2013-12-17T17:58')
If you specifically DID have a date/time range to consider, THEN you could do something like
WHERE YourTable.Column BETWEEN CTOT( '2013-12-05T10:00') AND CTOT( '2013-12-14T11:58')
PROBLEMS WITH your DATE() and TIME() implementations
The problem is Date() is a function to either return current date, or create based on y/m/d provided such as date( 2013, 12, 7 ). If you are passing a string, use CTOD( 'mm/dd/yyyy' ) such as CTOD( 12, 7, 2013 ).
As for the TIME() function that just expects a number and is of no use for you. From the OleDbProvider, your best bet is to just create a php function that builds a single string in the CTOT() format I've described and pass to the php function the date and time fields. Then use that as your "CTOT( functionReturnResult )"
To add a Date and a Time Field together you will need to convert them both to a same datatype 1st and than just simply add them together something like this....
DECLARE #D DATE = '2013-12-17'
DECLARE #T TIME = '17:58:00'
SELECT CAST(#D AS DATETIME) + CAST(#T AS DATETIME)
Result
2013-12-17 17:58:00.000
Your Query
SELECT top 10 *
from invoices
WHERE CAST(invDate AS DATETIME) + CAST(invTime AS DATETIME)
BETWEEN '20131217 17:58:00.000' AND GETDATE()