What is the purpose of the string "- 4/24" from a record that holds a date? - sql

I have an already generated script that uses the following code: ORDER BY TO_CHAR((A.VERIFIED_DTTM - 4/24),'YYYY-MM-DD'). The output of A.VERIFIED_DTTM is a simple date eg: 09-SEP-19.
I was my understanding that 4/24 is the same as saying 4 hours. I have tried removing this string from my query and received radically different results (not just sorting or ordering).
In another area of the script, I have a code that makes excellent sense (A.VERIFIED_DTTM >= sysdate - 30). This I understand.
Can anyone explain what is actually happening with this query line?
Thank you!

It is subtracting 4 hours and converting the date value to a string in the format of YYYY-MM-DD. This is probably a timezone adjustment.
To be honest, I'm not sure why it doesn't just use:
ORDER BY A.VERIFIED_DTTM
Removing it should not radically change the results.

Related

How to check that cells contain data in date format (oracle)

I need verify that all cells in column contain data in only date format. How it possible to verify?
*I think it isn't LIKE function.
DATE doesn't have any format. What you see is for display purpose so that it could be easily interpreted.
DATE datatype is stored in a proprietary format internally in 7 bytes. It is a bad idea and makes no sense to verify the format while date is stored in an internal format. As I said, format is only for display.
If the date column is not a DATE data type, then it is a design flaw. And, any application based on such a flawed database design is on the verge to break anytime.
Storing DATE values other than date data type is just like not understanding the basics.
You should first fix the design to get a permanent solution. Any solution to your question is just another workaround.
Let me show a small example how it creates even more confusion.
The following date :
01/02/2015
Is it:
1st Feb 2015 or,
2nd Jan 2015
There is no way to tell that. It could be either DD or MM. This being just one among so many other problems due to the incorrect data type.
Store date values as DATE data type only, period.
Based on your last question, I think you are looking for something like this:
SELECT COUNT(*) FROM ...
WHERE NOT REGEXP_LIKE (A, '^XXX/MOSCOW/XXXMSX/[0-9]{4}-[0-9]{2}-[0-9]{2}$')
If count is greater than zero, something doesn't match. If you want more detail on what doesn't match, change your SELECT clause appropriately.
If you are looking for multiple date formats, you can change your regular expression appropriately. The | operator in most flavors of regular expression, including Oracle's, lets you define multiple patterns in the same space. You might use something like
SELECT COUNT(*) FROM ...
WHERE NOT
REGEXP_LIKE (A,
'^XXX/MOSCOW/XXXMSX/[0-9]{4}-[0-9]{2}-[0-9]{2}$|^[0-9]{4}-[0-9]{2}-[0-9]{2}$')
adding as many different matching patterns as you need.
Try
SELECT *
FROM POL
WHERE NOT REGEXP_LIKE(TR_KRY, '^(0[1-9]|([1-2][0-9])|30|31)-(([0][1-9])|10|11|12)-[0-9]{4}$')
This will return you all rows where TR_KRY is not formatted as 'DD-MM-YYYY', where DD is '01'-'31', MM is '01'-'12', and YYYY is any four numeric digits.
As others have said, storing dates as character strings is not a good idea. In the field you're looking at, it might be that the date is stored as DD-MM-YYYY (day-month-year - the usual case in Europe and perhaps elsewhere), or it might be that the date is stored as MM-DD-YYYY (month-day-year - a common practice in the US). If possible, I suggest you should convert this field to the DATE data type so that the TO_CHAR function can be used to produce a text version of the date in whatever format is desired.
Given the example data you've shown in comments (and that's also not good practice - you should go back and edit the question when you want to include additional information) it appears the dates are formatted as DD-MM-YYYY and I've set up the regular expression above to deal with this as best as possible.

Date Range Query not returning all records - SQL

I have a SQL db that I need to filter results based on the month that inventory items were completed in order to do the billing.
The field I'm working with is called CompletionDate. Here is the code I'm using.
input name='criteria' type='hidden' value="WHERE CompletionDate BETWEEN '8-1-2013' AND '8-31-2013'"
I get some of the records returned but not all. I suspect that the problem lies in the format of the CompletionDate field. It is currently a varchar(10). I am storing the data in this field in the format MM-DD-YYYY.
After some searching I understand that since the field is in a varchar datatype that the above mentioned code is not going to work the way I want it to. I've tried this to no avail.
input name='criteria' type='hidden' value="WHERE to_date(CompletionDate, 'mm-dd-yyyy') BETWEEN to_date('8-1-2013', 'mm-dd-yyyy') AND to_date('8-31-2013', 'mm-dd-yyyy')"
Can anyone help guide me to the solution?
Because the field is of type varchar, you are not searching for a date range but actually a text range. You really should store dates in a date type field, because then you can easily and efficiently do date range queries.
Your workaround using to_date should in theory work, although it is rather inefficient as the database has to try to convert the text from each row into a real date in order to be able to do the comparison. As to why it actually does not work is still unclear. What database are you using? Is the format string correct or should it be in uppercase ('MM-DD-YYYY')?
If you are stubborn in storing dates as text in the database, using a format that can be lexically sorted, e.g. YYYY-MM-DD including leading zeroes (2013-08-01), can seemingly make the range queries work. But there really are several good reasons why databases have dedicated date datatypes!
A better way is like this:
where CompletionDate >= the start of your date range
and CompletionDate < the day after the end of your date range.
Reason number 1 is that it will take the time element into account, if applicable.
Reason number 2 is that using functions in the where clause slows down production.
By the way, if CompletionDate is a char or varchar datatype in your db, you have serious problems.

date handling in sqlite3 confusing.

I am from non database background. I have created a table with one of the field data type TEXT.
dataF TEXT
INSERTION:
Have inserted three records with the values :
'842-2-4'
'842-2-5'
'842-2-6'
SELECTION:
Tring to get the records based on date now.
... where dateF between '842-2-4' and '842-2-10'
It fails.
Whereas,
... where dateF between '842-2-4' and '842-2-8'
retrieves all the 3 records.
What am i doing wrong ? Why the first statment fails ?
Kindly suggest.
Because you are comparing strings not dates. The computer has no idea these are dates. You have to either store as date and do a date comparison or implement your own logic to analyze strings.
Simply put, it is looking at the 1 in 10 as being less than your values rather than 10 being more. It's string comparison, not date.
Although sqlite doesn't support date types, it does have functions for dealing with them. See here:
http://www.sqlite.org/lang_datefunc.html
When comparing strings, the values are compared left to right...
As one string is shorter that the other, you are kind of comparing this...
'842-2-4'
'842-2-1'
Well, nothing is >= '842-2-4' AND <= '842-2-1'.
Because '842-2-1' comes before '842-2-4'.
And, so, '842-2-10' comes before '842-2-4' too.
Just as 'Squiggled' comes before 'Squiggly'
And as 'xxx-y-az' comes before 'xxx-y-z'
To compare as you desire, make sure all your dates are padded with 0's.
BETWEEN '0842-02-04' AND '0842-02-10'
But that will only work after you have padded out the values in your table too.
EDIT:
Also, note that this assumes that your format is YYYY-MM-DD. As a string is compared left to right, you must have the highest magnitude values to the left.
(This means that you can't use YYYY-DD-MM and still have native string comparisons behave as you would want them.)

change postgres date format

Is there a way to change the default format of a date in Postgres?
Normally when I query a Postgres database, dates come out as yyyy-mm-dd hh:mm:ss+tz, like 2011-02-21 11:30:00-05.
But one particular program the dates come out yyyy-mm-dd hh:mm:ss.s, that is, there is no time zone and it shows tenths of a second.
Apparently something is changing the default date format, but I don't know what or where. I don't think it's a server-side configuration parameter, because I can access the same database with a different program and I get the format with the timezone.
I care because it appears to be ignoring my "set timezone" calls in addition to changing the format. All times come out EST.
Additional info:
If I write "select somedate from sometable" I get the "no timezone" format. But if I write "select to_char(somedate::timestamptz, 'yyyy-mm-dd hh24:mi:ss-tz')" then timezones work as I would expect.
This really sounds to me like something is setting all timestamps to implicitly be "to_char(date::timestamp, 'yyyy-mm-dd hh24:mi:ss.m')". But I can't find anything in the documentation about how I would do this if I wanted to, nor can I find anything in the code that appears to do this. Though as I don't know what to look for, that doesn't prove much.
Never mind :'(
I found my problem. I was thinking that I was looking directly at the string coming back from the database. But I was overlooking that it was reading it as a Timestamp and then converting the Timestamp to a string. This was buried inside a function called "getString", which is what threw me off. I was thinking it was ResultSet.getString, but it was really our own function with the same name. Oops. What idiot wrote that function?! Oh, it was me ...
Thanks to all who tried to help. I'll give you each an upvote for your trouble.
I believe the table columns are specified differently. Try these variants:
timestamp
timestamp(0) no millis
timestamptz with timezone
timestamptz(0) with timezone, no millis
With which client are you running the select statements? Formatting the output is the application's responsibility, so without knowing which application you use to display the data, it's hard to tell.
Assuming you are using psql, you can change the date format using the SET command:
http://www.postgresql.org/docs/current/static/sql-set.html
Which is essentially a way to change the configuration parameters. The ones that are responsible for formatting data are documented here:
http://www.postgresql.org/docs/current/static/runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT
Daniel tells me to post my findings as an answer and accept it to close the question. Okay.
I found that the date format I was seeing that did not include a time zone was not what was coming directly from Postgres, but that there were a couple of function calls that I was missing that converted the incoming date to a java.util.Timestamp, and then from the java.util.Timestamp to a String. It was in this conversion from the Timestamp to the String that the time zone was defaulting to EST.
In my own humble defense, my mistake was not as dumb as it may sound. :-0 We had the execution of the query in a subclass that read the results into a List, which we do to allow modification of the query results before output. (In this case we are adding a coule of columns that are derived from the stored columns.) Then we have a set of functions that resemble the JDBC functions to pull the data out of the List, so a calling program can easily switch from processing a query directly to processing the List. When I was wrestling with the date format problem, it just didn't register on me that I wasn't looking at "real JDBC", but at "simulated JDBC" calls.

sql server 2008: bcp_sendrow, issue: invalid time format

I'm having a problem "Invalid time format" when I try to use bcp functions(bcp_sendrow/bind etc.) to insert into a table having a datetime column.
so as per googled examples, I populated a DBDATETIME structure, for example: if I wanted to populate 3rd august 2009, exactly 8am localtime, I'd populate the structure members like so:
dtdays=40026(num days since 19000101) and
dttime = 28800000 (num millisecs since midnight)
(Also having bound the var. as a SQLDATETIME)
if dttime is 7 digits wide(or less), then bcp suceeds(but obviously with a wrong time value (date part is ok) )
how can I sort this out? I've tried datetime2 /time etc. but nothing helped.
please help , all advice/ideas most appreciated.
(I'm using Sql server 2008, and (ODBC) sql native client 10.0)
thanks!
never mind.. got it finally (sort of)
-DBDATETIME::dttime (num of millisecs since start of day) needs to be DIVIDED by 3.333333..
that way you get to the closest value to represent your time. (the field width is only 7 digits wide)..this probably has something to do with datetime type being able to represent only 1/3rd of a sec. accurately....
anyways, I tried using datetime2 with ODBC bcp api , but couldn't make the time part work
please let me know if anyone finds a better way
thanks!