Converting String to Date with SQL in DB2 - sql

a similar question has been asked, but the examples use different formats so I haven't been able to solve my problem. For some reason, the database my company uses stores dates as the following:
1131112
1130919
The first is November 12, 2013; the second is September 19, 2013. Not sure why there is a 1 at the beginning. I am trying to convert it to mm/dd/yy so I can use VBA to just grab invoices that are within a user specified date.
The code I am using is the following which results in a database error '1004':
SELECT date(translate('xyymmdd',INDATE,'mmddyy')) FROM INVOICED WHERE (INMFGR || INCOLO || INPATT = 'MMMTEST')

Depending on your DB2 version and platform (which you strangely did not indicate), you might be able to do something like
select to_date(substr(INDATE,2),'yymmdd') from INVOICED
PS. Your use of translate() seems wrong. You can look up its proper usage in the manual for the appropriate DB2 version.

Related

SQL Server : best practice query for date manipulation

Long time listener, first time caller.
At work we have all of the date columns for most tables stored in as a simple "string" (varchar) formats. Such as yyyymmdd (eg. 20220625) or yyyymm (202206) etc.
Now for a lot of queries that are time based we need to compare to current date, or some fixed offset from current date.
Now two obvious versions that I know of to get current utc date into either of those formats are the following (for yyyymm as example):
SELECT LEFT(CONVERT(VARCHAR, GETUTCDATE(), 112), 6) ...
SELECT CONVERT(VARCHAR(6), GETUTCDATE(), 112) ...
I'm wondering if anyone knows of a better way, either both idiomatically or performance wise to convert those, and/or is there anything wrong with the second one to be worried about versus the first one in regards to either security/reliability etc? The second one definitely satisfies my code golf sensibilities, but not if it's at the expense of something I'm unaware of.
Also for some extra context the majority of our code runs in SQL Server or T-SQL, BUT we also need to attempt to be as platform agnostic as possible as there are customers on Oracle and/or Mysql.
Any insight/help would be highly appreciated.
There is no problem with either approach. Both work just fine. It is a matter of personal preference which to choose. The first looks more explicit, the second is shorter and thus easier to read maybe. As to performance: You want to get the current day or month only once in a query, so the call doesn't realy affect query runtime.
As to getting this platform agnostic is quite a different story. SQL dialects differ. Especially when it comes to date/time handling. You already notice that SQL Server's date functions are quite restricted. In Oracle and MySQL you would simple state the format you want (TO_CHAR(SYSDATE, 'YYYYMM') in Oracle and DATE_FORMAT(CURRENT_DATE, '%Y%m') in MySQL). But you also see that the function calls differ.
Now, you could write a user defined function GET_CURRENT_MONTH_FORMATTED for this which would return the string for the current month, e.g. '202206'. Then you'd have the different codes hidden in that function and the SQL queries would all look the same. The problem, though, is how to tell the DBMS that the function result is deterministic for a particular timestamp? If you run the query on December 31, 2022 at 23:50 and it runs until January 1, 2023 at 0:20, you want the DBMS to call this function only once for the query resulting in '202212' and not being called again, suddenly resulting in another string '202301'. I don't even know whether this is possible. I guess it is not.
I think you cannot write a query that does what you want and looks the same in all mentioned DBMS.

Substituting SQL double pipe In Crystal Reports

I would like to remove the SQL in crystal reports and filter it with the equivalent logic in the select expert tool to make the migration from a older version to a newer version easier.
The issues that I've run into is a SQL query like the following
WHERE YEAR||MONTH >= '201504'
AND WHERE YEAR||MONTH <='201602'
Intuitively this makes sense, a query where between April 2015 and February 2016.
I don't see how this is possible in the Select Expert tool as I can indicate the year and month and values they can be between, but not specify a range like the one indicated above.
Essentially if its possible to rewrite this statement using the basic operators ('<' '<=' '=') for my year and month, that would solve my problem. Thanks!
{table.year}&{table.month} in ("201504" to "201602")
or if your fields are numbers
totext({table.year},"#")&totext({table.month},"#") in ("201504" to "201602")

oracle sql developer(4.0.0.12) returns wrong date

It seems that a query of mine returns wrong results, and I'm not sure why. I don't yet rule out the possibility that the SQL is actually doing something else then what I expect/want it to do since I haven't used SQL for a time now.
I post it here because I'm kind a stuck with the why it returns wrong results sometimes.
The error is in the MIN(FIRM.account_recharge.X__INSDATE) (or at least the ones I noticed)
SELECT
FIRM.customer.CUSTOMER_ID,
FIRM.customer.CORPORATION,
FIRM.customer.CUSTOMER_NAME_PREFIX,
FIRM.customer.CUSTOMER_NAME,
FIRM.account.ACCOUNT_TYPE,
FIRM.account.ACCOUNT_TYPE,
FIRM.customer.LANGUAGE,
FIRM.customer.VALIDATED,
FIRM.account.X__INSDATE,
SUM(FIRM.account_recharge.GROSS_VALUE) SUM_FELTOLTESEK,
MIN(FIRM.account_recharge.X__INSDATE),
INNER JOIN FIRM.account
ON FIRM.customer.CUSTOMER_ID = FIRM.account.CUSTOMER
INNER JOIN FIRM.customer_address
ON FIRM.account.CUSTOMER = FIRM.customer_address.CUSTOMER
INNER JOIN FIRM.account_recharge
ON FIRM.account.ACCOUNT_ID = FIRM.account_recharge.ACCOUNT
GROUP BY FIRM.customer.CUSTOMER_ID,
FIRM.account.X_INSDATE,
FIRM.customer.CORPORATION,
etc,etc
HAVING MIN(FIRM.account_recharge.X__INSDATE) BETWEEN to_date('2014-JAN. -01','YYYY-MON-DD') AND to_date('2014-DEC. -31', 'YYYY-MON-DD');
This code should return information abut our customers, their sum account 'recharging'/'replenishing'/'paying in' , sorry not sure of what word to use here. and their first payment/money upload to their account in 2014. Yet sometimes the return values seems to just ignore the actual first time our client paid in money, and shows the second or third date. (my random manual check returned that around 1/10 of the time the returned values are wrong.)
A costumer of ours can have more the one account linked to him. I'm using Oracle SQL developer (4.0.0.12) please ask if you would like to know anything else about this pickle im in.
Otherwise It seems to work nicely, but if you have any other tuning tip, I would be glad to hear them.
Thank you for your help!
HAVING MIN(FIRM.account_recharge.X_INSDATE) BETWEEN '14-JAN. -01' AND '14-DEC. -31'
This is definitely incorrect. You are comparing dates. so, you must convert the string literal explicitly into a date using TO_DATE and proper format mask.
For example,
HAVING MIN(FIRM.account_recharge.X_INSDATE)
BETWEEN to_date('2014-JAN-01','YYYY-MON-DD')
AND to_date('2014-DEC-31', 'YYYY-MON-DD')
Also, do not use YY to denote the year. You don't have to re-invent the Y2K bug again. Always use YYYY format for an year. Else, if you are stuck with YY values for year, then use RR format. But, I would insist, always use YYYY format for year.

Microsoft Access 2010 Date Conversion

I don't have much experience so I apologize in advance for a potentially dumb question. I did not create these tables nor the queries that have been used in the past. With that said --
For the past several months I have been using a date conversion query that was given to me to update columns from an integer to a date. It used to work just fine and I swear everything is the same for my latest data extractions, but at some point the dates started getting wonky. For example, a typical date column might look like:
58222
58158
59076
58103
And the conversion query looks something like this:
IIf([D_posting]<>0,[D_posting]-18261,0)
And returns the above dates as:
05/27/2059
03/24/2059
09/27/2061
01/28/2059
Which obviously is wrong. The situation kind of reminds me of how I remember we generated random numbers in C++ (which was a long time ago), but for the life of me I can't figure out how to reverse engineer the correct subtraction factor without a reference point.
I also tried using the CDate() function instead, and it resulted in a bunch of future dates also, leading me to wonder if there's something else wrong. I work for a small physicians group so it might be something in the Electronic Health Records software, but I'd like suggestion on what I should check to make sure it's nothing that I've done.
You could create a query that uses the 'cdate' function (see below) to return the date. You can modify the code so that it subtracts the offset (maybe 18261?)
In the immediate window of VBA you can tinker with the following:
The 'cdate' will take a number and convert it to a date:
?cdate(41925)
10/13/2014
The 'cdbl' will take a date and convert to a number.
?CDbl(Date())
41926

Constructing an sql Query to get records betwen two dates

I'm trying to filter out and report records in a database that fall between a specified date range. I'm there are other threads here on how to do something similar, but my dates are stored as date timestamps (which is why I think the issue is arising)
My current query is as follows:
"SELECT * FROM JOURNAL WHERE Date_Time>'10/10/2013 00:00:00'"
(Note that journal is the name of the table I'm pulling the data from and date_time is the field in which the date is stored. I'm aware the query doesn't quite do what I want it to yet, but I was just testing out a simpler case at first.)
When I run this query (as part of an excel macro), excel reports that it can't find any records even though I know their are records past this date. Does anyone know how to do this properly?
Edit: I've got it, it was an issue unrelated to the query (something else in the macro) Thanks so much for the help (changing the date format worked)
have you tried other date format? like this:
"SELECT * FROM JOURNAL WHERE Date_Time>'2013-10-10:00:00:00'"
A simple between statement is what you need:
SELECT * FROM JOURNAL WHERE Date_Time between '10/10/2013 00:00:00' and '[otherdate]'
You need to run this to check for one important thing: If the server is running the BETWEEN as inclusive or not. If it's inclusive, both dates are included. If not, the range will begin either before or after one or both.
I've seen SQL servers that are the same in every respect actually treat this condition differently. So it's a good idea to check that.