How to format date in where? - sql

I have this script:
select * from OPDN A
where A."DocDate" between '2020/01/01' and '2020/01/31'
How to achieve the format "MM/DD/YYYY" in the WHERE clause?
select * from OPDN A
where A."DocDate" between '01/01/2020' and '01/31/2020'
The column DocDate is of type TimeStamp.

If the column data type is TIMESTAMP as the OP has written in a comment to Sandra Rossi's excellent answer then there are actually three conversions required to make the selection work as expected.
turn the first selection parameter (between a ...) into a date
turn the second selection parameter (between ... and b) into a date
turn the timestamp column DocDate into a date
This looks like this:
select
*
from
OPDN A
where
to_date(A."DocDate") between to_date('01/01/2020', 'MM/DD/YYYY')
and to_date('01/31/2020', 'MM/DD/YYYY');
The conversion of the selection parameters with the help of format-strings should be obvious, and the result is the same information in a SQL date data type.
The third conversion (to_date(a."DocDate")) might be surprising, but is rather important.
The way the selection is meant to work is to include everything from the very start of the selection period to the very end. If the input filters are simply converted to timestamps then they will have the time-component of 00:00 (midnight), as no specifics about the time of day are provided.
This will lead to all "DocDate" values after midnight to be excluded.
The correct level of comparison here is date, therefore the "DocDate" also needs to be converted to the hour-less date data type.
p.s. I just realized that the selection criteria are given in MM/DD/YYYY format which is probably the reason for the conversion error the OP received earlier.

It depends what is the type and format of the column DocDate.
In SAP ERP softwares (R/3, ECC, S/4HANA), the dates were historically defined as NVARCHAR types of 8 characters, with the format 'YYYYMMDD'.
In SAP Business One, I don't know...
In SAP HANA database, there are also four specific types (SAP Library "Datetime Data Types"): DATE, TIME, SECONDDATE, TIMESTAMP.
Solutions for each case:
If DocDate type is NVARCHAR 8 with format YYYYMMDD: select * from OPDN A where A."DocDate" between '20200101' and '20200131'
In SAP Business One, I don't know...
If DocDate type is DATE: select * from OPDN A where A."DocDate" between to_date('01/01/2020','DD/MM/YYY') and to_date('01/31/2020', 'DD/MM/YYY')

In Oracle, it can do that
select * from OPDN A
where to_date(A."DocDate", 'DD/MM/YYY') between to_date('01/01/2020','DD/MM/YYY') and to_date('01/31/2020', 'DD/MM/YYY');

Related

SQL query to bring back list of servers from specific date range

I'm trying to make a query with SQL Server Management Studio 2017 that brings back a count of all the servers with a projected migration date of this year. I have one query made now, but it's still bringing back some servers with dates from years before.
SELECT MONTH(Projected) as [Month], count(*) as [Total]
FROM dbo.tFake
WHERE Projected >='01/01/2019' AND Projected <='12/31/2019
GROUP BY Month(Projected)
ORDER BY [Month]
Date format is mm/dd/yyyy btw. How can I get this query to bring back just servers that are projected for the year 2019?
Going by the assumption that your data type is wrong, the first step is to fix that.
Note, I am assuming that your data only contains dates, and not time (which your query implies). Firstly, you'll need to change the value of all your rows to an convertible value, we'll go with the ISO format yyyyMMdd:
UPDATE dbo.tFake
SET Projected = CONVERT(varchar(8),CONVERT(date,Projected,101),112);
Now that all the rows are a literal string in the format yyyyMMdd we can alter the column:
ALTER TABLE dbo.tFake ALTER COLUMN Projected date;
Now, we can run your query again, but now your data type is correct, you won't have the problem:
SELECT MONTH(Projected) as [Month], count(*) as [Total]
FROM dbo.tFake
WHERE Projected >= '20190101' AND Project < '20200101' --I prefer the >= and < method. This is especially import with date & time data types
GROUP BY Month(Projected)
ORDER BY [Month];
Notice the literal strings I passed are also in the yyyyMMdd format. If you must pass a literal string in the format MMddyyyy you can wrap in a CONVERT with the style code 101: CONVERT(date,'12/31/2019',101). 101 means the US style date (CAST and CONVERT (Transact-SQL).
Remember, this solution assumes you have date only values, and not date and time values. If you do (have date and time values) you'll want to use an appropriate date and time data type and use the ISO8601 style, instead of the ISO style.

DB2 Convert Number to Date

For some reason (I have no control over this) dates are stored as Integers in an iSeries AS400 DB2 system that I need to query. E.g. today will be stored as:
20,171,221
Being in the UK I need it to be like the below in Date format:
21/12/2017
This is from my query: (OAORDT = date field)
Select
Date(SUBSTR( CHAR( OAORDT ),7,2) ||'/' || SUBSTR(CHAR ( OAORDT ),5,2) || '/' || SUBSTR(CHAR (OAORDT ),1,4)) AS "Order Date"
from some.table
However, all I get is Nulls. If I remove the Date function, then it does work but its now a string, which I don't want:
Select
SUBSTR( CHAR( OAORDT ),7,2) ||'/' || SUBSTR(CHAR ( OAORDT ),5,2) || '/' || SUBSTR(CHAR (OAORDT ),1,4) AS "Order Date"
from some.table
How do I convert the OAORDT field to Date?
Just to update - I will be querying this from MS SQL Server using an OpenQuery
Thanks.
1) How do I convert the OAORDT field to Date?
Simplest is to use TIMESTAMP_FORMAT :
SELECT DATE(TIMESTAMP_FORMAT(CHAR(OAORDT),'YYYYMMDD'))
2) Being in the UK I need it to be [...] in Date format 21/12/2017 :
SELECT VARCHAR_FORMAT(DATE(TIMESTAMP_FORMAT(CHAR(OAORDT),'YYYYMMDD')),'DD/MM/YYYY')
Note, you didn't specify where you are doing this, but since you tagged as ibm-midrange, I am answering for embedded SQL. If you want JDBC, or ODBC, or interactive SQL, the concept is similar, just the means of achieving it is different.
Make sure SQL is using dates in the correct format, it defaults to *ISO. For you it should be *EUR. In RPG, you can do it this way:
exec sql set option *datfmt = *EUR;
Make sure that set option is the first SQL statement in your program, I generally put it immediately between D and C specs.
Note that this is not an optimal solution for a program. Best practice is to set the RPG and SQL date formats both to *ISO. I like to do that explicitly. RPG date format is set by
ctl-opt DatFmt(*ISO);
SQL date format is set by
exec sql set option *datfmt = *ISO;
Now all internal dates are processed in *ISO format, and have no year range limitation (year can be 0001 - 9999). And you can display or print in any format you please. Likewise, you can receive input in any format you please.
Edit Dates are a unique beast. Not every language, nor OS knows how to handle them. If you are looking for a Date value, the only format you need to specify is the format of the string you are converting to a Date. You don't need to (can't) specify the internal format of the Date field, and the external format of a Date field can be mostly anything you want, and different each time you use it. So when you use TIMESTAMP_FORMAT() as #Stavr00 mentioned:
DATE(TIMESTAMP_FORMAT(CHAR(OAORDT),'YYYYMMDD'))
The format provided is not the format of the Date field, but the format of the data being converted to a Timestamp. Then the Date() function converts the Timestamp value into a Date value. At this point format doesn't matter because regardless of which external format you have specified by *DATFMT, the timestamp is in the internal timestamp format, and the date value is in the internal date format. The next time the format matters is when you present the Date value to a user as a string or number. At that point the format can be set to *ISO, *EUR, *USA, *JIS, *YMD, *MDY, *DMY, or *JUL, and in some cases *LONGJUL and the *Cxxx formats are available.
Since none of variants suited my needs I've came out with my own.
It is as simple as:
select * from yourschema.yourtable where yourdate = int(CURRENT DATE - 1 days) - 19000000;
This days thing is leap year-aware and suits most needs fine.
Same way days can be turned to months or years.
No need for heavy artillery like VARCHAR_FORMAT/TIMESTAMP_FORMAT.
Below worked for me:
select date(substring(trim(DateCharCol), 1, 2)||'/'||substring(trim(DateCharCol), 3, 2)||'/'||'20'||substring(trim(DateCharCol), 5, 2)) from yourTable where TableCol =?;

How do I display DATE in 'DD MON YYYY' format?

I am a newbie for Oracle database programming and I wish to INSERT date (also display) in 'DD MON YYYY' format. (PS: This only involves INSERT event). Which data type (DATE or TIMESTAMP) is the most suitable option for me in order to accomplish this format? How was I supposed to do that? Thanks.
A DATE column does not have any format.
So the format that you use when inserting or updating data is irrelevant for displaying that data (that's one of the reasons why you should never store a date in a VARCHAR column).
Any formatted output you see for a DATE column in your SQL tool (e.g. SQL*Plus) is applied by that tool. It is not part of the data stored in that column.
When providing a date literal you should either use the to_date() function with an explicit format mask:
insert into some_table (some_date_column)
values (to_date('27-06-2014', 'dd-mm-yyyy'));
I also do not recommend using formats with written month names (27-JUN-2014) when supplying a date literal because they also depend on the NLS settings of the client computer and might produce (random) errors due to different languages. Using numbers only is much more robust.
I prefer to use ANSI date literals because it's a bit less typing:
insert into some_table (some_date_column)
values (DATE '2014-06-27');
The format for an ANSI date (or timestamp) literal is always the ISO format (yyyy-mm-dd).
When you select your data you can display the date in whatever format you like. Either by using the to_char() function (e.g. when using a SQL tool) or using functions from your programming language (the preferred way to use inside an application):
select to_char(some_date_column,'dd-mon-yyyy')
from some_table;
Note that the DATE data type in Oracle (despite it's name) also stores the time. a TIMESTAMP does the same thing only with a higher precision (it includes milliseconds, whereas the DATE data type only stores seconds).
To insert a record,
INSERT INTO TABLE_NAME (DATE_FIELD) VALUES (TO_DATE ('27-JUN-2014', 'DD-MON-YYYY');
It is advisable to use DATE data-type until and unless you need the date's accuracy to be till milli seconds. In your case, go with DATE datatype and TIMESTAMP is not necessary
To select a record,
SELECT TO_CHAR(DATE_FIELD, 'DD-MON-YYYY') FROM TABLE_NAME;
In genral, remember this:
TO_DATE is a function used to convert a string(CHAR) TO DATE
TO_CHAR is a function used to convert a DATE to a string(CHAR)
In this scenario date datatype will be suitable for you, and for the desired format you should try like this:-
INSERT INTO TABLE_NAME(DATE_COLUMN) VALUES('27-JUN-2014');
Hope this can help you.

selecting data fom a view throws error

I get input as 2011/11/13 00:00:00. So I made the query as:
select * from xxcust_pfoa434p_vw
where week_ending_date = to_date(substr(:value,1,10),'YYYY/MM/DD')
The same statement gives proper result when queried against other tables. But throws error when I query this against the view xxcust_pfoa434p_vw
I have a view xxcust_pfoa434p_vw which has a column week_ending_date of date data type.
The value in that column is like 3/2/2014,12/25/2011 i.e. MM/DD/YYYY
Even
select * from xxcust_pfoa434p_vw where week_ending_date='3/2/2014'
also gives
ORA-01843: not a valid month. What is the cause for this error.
You say
"The same statement gives proper result when queried against other
tables. But throws error when I query this against the view
xxcust_pfoa434p_vw"
So clearly the problem is with the view. You also say
"[the view] has a column week_ending_date of date data type. The value
in that column is like 3/2/2014,12/25/2011 i.e. MM/DD/YYYY "
Those values would only display like that if the default date mask for you system were MM/DD/YYYY. This is easy enough to check with the query
select * from V$NLS_PARAMETERS
where parameter = 'NLS_DATE_FORMAT';
Personally, my money is on that column not being a date column. ORA-01841 always indicates oracle attempting to cast a string into a date and finding a value which doesn't fit the explicit or default format mask. Plus the so-called date '3/2/2014' lacks leading zeroes and that's suspicious too.
I think whoever wrote that view decided to fix the format of week_ending_date and so deployed TO_CHAR to present a string not a date datatype. A DESC in SQL*Plus or looking at the view TEXT in ALL_VIEWS will reveal the answer.
select * from xxcust_pfoa434p_vw
where week_ending_date=to_date('03/02/2014','MM/DD/YYYY');
Even if you see formatted date in this format - it is only a visual representation, when oracle process your query it automatically convers string given by you into its own interal representation.
It is always better to use proper SQL one YYYY-MM-DD:
for 2nd march: select * from xxcust_pfoa434p_vw where week_ending_date = to_date('2014-03-02', 'YYYY-MM-DD')
for 3rd february: select * from xxcust_pfoa434p_vw where week_ending_date = to_date('2014-02-03', 'YYYY-MM-DD')
this conforms to SQL standard and do not produce confusion between DD/MM/YYYY and MM/DD/YYYY
Just quote from standard:
There is an ordering of the significance of <datetime field>s. This
is, from most significant to least significant: YEAR, MONTH, DAY,
HOUR, MINUTE, and SECOND.
UPDATE: it is very good idea always use to_date function to specify exact format and avoid dependancy on any kind of localization settings

creating table in Oracle with Date

I want to create a table in Oracle 10g and I want to specify the date format for my date column. If I use the below syntax:
create table datetest(
........
startdate date);
Then the date column will accept the date format DD-MON-YY which I dont want.
I want the syntax for my date column to be MM-DD-YYYY
Please let me know how to proceed with this.
Regards,
A DATE has no inherent format. It is not simply a string that happens to represent a date. Oracle has its own internal format for storing date values.
Formats come into play when actual date values need to be converted into strings or vice versa, which of course happens a lot since interactively we write dates out as strings.
The default date format for your database is determined by the settings NLS_DATE_FORMAT, which you probably have set to DD-MON-YYYY (which I believe is the default setting for American English locales). You can change this at the database level or for a single session for convenience, but in general it is safer programming practice to be explicit so that you don't get errors or, worse, wrong results if your code is run in a different environment.
The simplest way to specify a date value unambiguously is a date literal, which is the word 'date' followed by a string representing the date in YYYY-MM-DD format, e.g. date '2012-11-13'. The Oracle parser directly translates this into the corresponding internal date value.
If you want to use a different format, then I recommend explicitly using TO_CHAR/TO_DATE with your desired format model in your code. Examples:
INSERT INTO my_table (my_date) VALUES ( TO_DATE( '11-13-2012', 'MM-DD-YYYY' ) );
SELECT TO_CHAR( my_date, 'MM-DD-YYYY' ) FROM my_table;
dates rdo not have a format like you're suggesting. they are stored internally as a 7 byte number. to format the date when selecting, please use TO_CHAR(yourdatefield, 'format')
where formats are all shown here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34924
eg to_char(startdate, 'mm-dd-yyyy')