convert decimal to date during where clause [duplicate] - sql

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Convert DB2 SQL Decimal to DATE
I have a db2 database and I want to convert a decimal to a date during the where clause in a select statement.
The decimal date could be 12 or 13 characters long depending on the month.
12 characters:
1,241,999.00 should become: 1999/1/24
13 Characters:
12,241,999.00 should become: 1999/12/24
The column name is DECIMALCOLUMN:
Select * from table1 WHERE
cast(replace(convert,DECIMALCOLUMN,date)) = #date

I see: You want some way of rearranging the digits of a number to become a date. It looks like the encoding is [m]mddyyyy. (Why isn't that a date datatype in the database?)
The number needs to be converted to a string and then substrings arranged and converted to a date. Given the complexities here, a conversion function should be written in lieu of the field being altered to be a proper datatype. Something like this should do it (untested, no access to db2):
create function decimaldate(decdate DECIMAL)
returns DATE
return
with tmp (dstr) as
(
select substr(digits (decdate),8)
from sysibm.sysdummy1
)
select
date (substr(dstr,4,4) || '-' ||
substr(dstr,1,2) || '-' ||
substr(dstr,3,2)
)
from tmp
This converts the number to a string, reformats the string as yyyy-mm-dd and converts to a date. (I used this as a basis.)
So the solution to the original question is simply to write:
SELECT *
FROM table1
WHERE decimaldate(DECIMALCOLUMN) = #date
With such a screwy way of encoding the date in the database, having the function always available should prove invaluable.

Related

Converting a numeric value into Date value in DB2

I have a DB2 table where NUM column is defined as INTEGER in DB2 and the query result is shown below,
NUM columns have numeric values which needs to be converted to date format. This numeric values are nothing but duration from 01.01.1850. Example : 01.01.1850 + 57677 days = 01.12.2007.
So Is it possible to convert or cast the numeric value into date fields in DB2 , so that the select query from the table can result as shown below after converting a numeric field into date field,
You may use the scalar ADD_DAYS function:
SELECT EMP_ID, ADD_DAYS('1850-01-01', NUM) AS NUM
FROM yourTable;
Not all Db2 products & versions have the ADD_DAYS function.
The following expression works for all of them.
You may optionally add DAY or DAYS at the end.
DATE ('1850-01-01') + 57677

Split a string than join, for cast

I have a table with this column
DATEFROM VARCHAR(8)
It's a string in the format 'yyyyMMdd'. I need to convert this element to Date Type.
I thought to split the string in 3 substrings (yyyy, MM, dd), than join them by adding '-' between the strings. In this way, i can cast to Date type.
How can I do it?
Repeating the answer that was posted in the question so that it doesn't show up as a question without an answer:
select cast(substring(datadal
from 1 for 4)||'-'||substring(datadal from 5 for 2)||'-'||substring(datadal from 7 for 2) AS DATE) as datadal

How to select records between two dates in Access? [duplicate]

This question already has an answer here:
Query to compare between date with time and date without time - python using access db
(1 answer)
Closed 4 years ago.
I need to select records with DateTime between two dates in an Access query. The problem is that when I'm execute this query:
select * from logs
where date_added >= CDate("01/10/2018")
AND date_added <= CDate("04/10/2018")
I need both border values but the result does not include the last day. Maybe because "04/10/2018" is converted to "04/10/2018 00:00:00" and this value is less than all date_added values of that day.
Can I convert date_added to date only?
Do you can add a day to your date?
AND date_added < DateAdd('d',1,CDate("04/10/2018"))
An alternative expression:
SELECT * FROM logs
WHERE DateValue(date_added) BETWEEN #01/10/2018# AND #4/10/2018#
Useful date functions and syntax:
Date literals can be delimited with # in both VBA code and SQL statements, so you don't have to call CDate() on string values. Examples: #10/6/2018 4:16 PM#, #1/1/2018#
Simple mathematical notation can be used to add and subtract whole days from a date value. Example: #10/6/2018# + 1 == #10/7/2018#
DateValue( val ) takes arguments of various formats and returns a date/time value with only the date portion. This answers your question Can I convert date_added to date only? It essentially returns the same date value with the time portion as 00:00:00.
Example: DateValue(#10/6/2018 4:16 PM#) == #10/6/2018#
DateAdd ( interval, number, date ) as already noted by Milad Aghamohammadi.
Within SQL only (not VBA), one can use the BETWEEN operator. It works with various data types that have a natural sort order, which includes date values.
Example ... WHERE [DateField] BETWEEN #1/1/2018# AND #4/1/2018#

Output of the query in oracle [duplicate]

This question already has answers here:
Equals(=) vs. LIKE for date data type
(3 answers)
Closed 5 years ago.
Query 1 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM = '25-JAN-13';
Result: 1
Query 2 :
select count(*) from CI_TXN_HEADER where TXN_HEADER_DTTM like '25-JAN-13';
Result: 19
In my DB I have 19 rows with TXN_HEADER_DTTM as 25-JAN-13.
Data Type of TXN_HEADER_DTTM is DATE.
Can someone please explain the difference in output?
An Oracle DATE column contains a date and a time. The LIKE condition is only for VARCHAR columns. If applied to other data types Oracle implicitly converts that to a varchar (using rules depending on the current client settings).
So you might have rows with e.g. 2013-01-25 17:42:01, however the string constant '25-JAN-13' is (most probably) converted to: 2013-01-25 00:00:00 and thus the = comparison doesn't work.
To find all rows for a specific day use trunc() and a proper date literal. Don't rely on the evil implicit data type conversion to specify date values.
Use trunc() to set the time part of a DATE value to 00:00:00:
I prefer ANSI SQL date literals:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = DATE '2013-01-25';
You can also use Oracle's to_date:
select count(*)
from CI_TXN_HEADER
where trunc(TXN_HEADER_DTTM) = to_date('2013-01-25', 'yyyy-mm-dd');
Note that Oracle can't use an index on TXN_HEADER_DTT, so if performance is critical use a range query:
select count(*)
from CI_TXN_HEADER
where TXN_HEADER_DTTM >= DATE '2013-01-25'
and TXN_HEADER_DTTM < DATE '2013-01-25' + 1;
The difference between like and equal is explained in this link very good
https://stackoverflow.com/a/2336940/4506285
I checked your problem on my table and I get the same results.
This link helps also to understand how to compare dates in sql
https://stackoverflow.com/a/18505739/4506285
Maybe your data consists of space, it is not exactly '25-JAN-13' but ' 25-JAN-13';
Please refer this two link:
Equals(=) vs. LIKE
What's the difference between "LIKE" and "=" in SQL?

Problems extending `format-string` with HH24MISS when converting decimal column based timestamp to actual timestamp

tl;dr
Why am I not able to convert following string timestamp
select timestamp_format('2015-08-21 000000', 'YYYY-MM-DD HH24MISS') as timestamp
from sysibm.sysdummy1;
on an i7.1.0/OS machine?
Especially since I can convert
select timestamp_format('000000' , 'HH24MISS') as timestamp
from sysibm.sysdummy1;
to:
timestamp
-------------------------
2015-08-01 00:00:00.000000
Context
On an i7.1.0/OS machine, I have a table with timestamp data split up in several decimal columns, like
declare global temporary table tstamp
(
year dec(4,0),
month dec(2,0),
day dec(2,0),
time dec(6,0)
);
with data like
insert into session.tstamp
values (2015,8,21,92601),
(2015,8,21,132601);
on which I want to do some date filtering. Given the somewhat inflexible format, I figured that it is probably better if I convert this to a timestamp and use this to query the table. So i consulted the i/OS 7.1 Manual on timestamp_format
I started of with building the date part, ending up with
select
timestamp_format(YEAR || '-' || MONTH || '-' || DAY, 'YYYY-MM-DD') as timestamp
from session.tstamp;
which returns
TIMESTAMP
--------------------------
2015-08-21 00:00:00.000000
2015-08-21 00:00:00.000000
Perfect, let us add the time part and explicit lpad it to contain six characters:
select
timestamp_format(YEAR || '-' || MONTH || '-' || DAY || ' ' || lpad(TIME, 6, '0'), 'YYYY-MM-DD HH24MISS') as timestamp
from session.tstamp;
This results in the following error:
SQL State: 22007
Vendor Code: -20448
Message: [SQ20448] Expression not valid using format string specified for TIMESTAMP_FORMAT. Cause . . . . . : Argument 1 of the TIMESTAMP_FORMAT function can not be interpreted using the format string specified in argument 2 for one of the following reasons: -- The string expression is too short or too long. -- The string expression does not conform to the template specified in the format string. -- Too many digits were specified in the string expression for the corresponding format element in the format string. -- A value in the string expression is not valid for the corresponding format element in the format string. Recovery . . . : Specify a valid format string for the function. Try the request again.
According to the manual regarding the format-string, a separator between fields is optional:
[...]
Two format elements can optionally be separated by one or more of the following separator characters:
[...]
Question
So why are not my values accepted when using 'YYYY-MM-DD HH24MISS' as the format-string, given that I explicit has bound the time length to six characters?
Side note
It is possible to use HH24MISS on its own as format-string, so I'm not really able to wrap my head around this.
select timestamp_format(lpad(TIME, 6, '0'), 'HH24MISS') as timestamp from session.tstamp;
TIMESTAMP
--------------------------
2015-08-01 13:26:01.000000
2015-08-01 09:26:01.000000
The difficulties described, are due to defects with the TIMESTAMP_FORMAT [aka TO_DATE] scalar. The requests shown are tested to have functioned, as expected, with the DB2 for IBM i 7.3 [and as a comment to the OP suggests, also on v7r2]. I had asked a similar question, "Why the failures using my earlier examples?" in SQL convert text mm/dd/yy to date and timestamp, but I have not yet re-visited those examples on the newer release. And FWiW, there may be some updated code on IBM i 7.1 for that feature with the latest code; I do not have that level of maintenance, so I can not test if the [the last of the] enhancements that are coming for that release include the code fixes that apparently exist in newer releases.
Note that the TO_DATE feature is not a true built-in [instead, is a system-supplied User Defined Function (UDF)], so personally, I would recommend an alternative; namely, writing and using a scalar UDF specific to the task, and/or choose a more compatible and easy way to generate the TIMESTAMP from those columns as they are defined. Consider the following expression [that assumes all dates are beyond year 1000, else the expression must change to use DIGITS(YEAR) vs just YEAR]:
timestamp( YEAR concat digits( MONTH ) concat digits( DAY )
concat digits( TIME )
)
A variation of that, is to use arithmetic to achieve the same effect of a 14–character timestamp-string form 'yyyymmddhhmmss':
timestamp( concat( YEAR * 10000 + MONTH * 100 + DAY
, digits ( TIME ) ) )
The following scalar function could be created to avoid coding the expression in [VIEW] queries or other places. As coded, with nothing but an expression on a RETURN statement, should allow in-lining; I did not specify any other potentially performance-related clauses such as parallel or on-null-input:
create function y4m2d2t6TS
( year dec(4, 0)
, month dec(2, 0)
, day dec(2, 0)
, time dec(6, 0)
) returns timestamp
language sql deterministic
return
digits( YEAR ) concat digits( MONTH )
concat digits( DAY ) concat digits( TIME )
; -- this semicolon is a statement separator, not terminator of above CREATE
select
y4m2d2t6TS( year, month, day, time ) as timestamp
from session.tstamp
; -- likeness of report from above query:
TIMESTAMP
2015-08-21-09.26.01.000000
2015-08-21-13.26.01.000000
******** End of data ***
You can use this in DB2 :
values(VARCHAR_FORMAT(current_date,'YYYY-MM-DD HH24:MI:SS'))
Bye