strange result for str_to_date in mysql - mysql

A developer created a table for us, and made a date field as VARCHAR(255) and a field name of "Requested Ship Date".
First yes I know these both are bad database management, but I was not involved at the creation point, just now in the please run reports against it point.
So, I am trying to convert this field to a date value, and was using STR_TO_DATE(Requested Ship Date,"%m/%d/%y") (it has the correct syntax in the code)
The problem is I am getting a weird result. 'Requested Ship Date' = 5/31/2017 after the conversion it comes out as 2020-05-31.
Thank you in advance.

%y is the year without the century, %Y is the year with the century.
So 2017 is being interpreted as '20, which is 2020.

This is the results I am getting from my query
05/30/2017 05/31/2017 2017-05-30
05/30/2017 05/31/2017 2017-05-30
05/31/2017 05/31/2017 2017-05-31
Here is the actual code for the Query
select `Requested Ship Date`,
`Actual Post Goods Issue date`,
STR_TO_DATE(`Requested Ship Date`,'%m/%d/%Y')
FROM `previous day shipments`
WHERE LENGTH(`Serial Number`) = 0

Related

How to standardize a dirty date field in MySQL

I have a MySQL table that contains column representing a date and is stored as a string.
The dates in this column (date) are not standard (dirty) and can range from
"Jan 5, 2004" or "Jun 22 2:45 AM"
For the records that are missing the year I have another column (OpeningDate) that can be null or "22 June 2005" and "Deadline" which is a dirty column with values like ("26 January 2004", "01 July 2005, 6 pm
ABOUT: BearingPoint, Inc. Commercial Law and Economic Regulation
Program")
How do I go about to get a normalized representation of the values in the date field.
For other tables I've been able to normalize the date field by using the following queries but for this table the solutions I come up with are too convoluted and not even close to accurate.
SELECT DATE_FORMAT(STR_TO_DATE(DATE,'%M %d, %Y'), '%Y-%m-%d') FROM `data job posts`
I'm not sure there is a clean way to do this since strings are very much non normalized. The cleanest approach would likely be to chunk the data being modified and identify patterns that are identifiable so that you can reduce the size of the dataset to a smaller group of highly unnormalized strings.
As an example something similar to this:
UPDATE table
SET DATE = CASE WHEN DATE LIKE '^alnum+, digit+$' THEN DATE_FORMAT(STR_TO_DATE(DATE,'%M %d, %Y'), '%Y-%m-%d') ELSE DATE END,
DATE = CASE WHEN DATE LIKE '^alnum+:alnum+$' THEN DATE_FORMAT(STR_TO_DATE(DATE,'%M %d %l:%i %p'), '%m-%d') ELSE DATE END;
It might help to create this as a new column and rename the new column when dropping the old one once the operation is complete or creating this as a new table if the current table is live and needs to be queryable as updating records may lock the table.

Get data from past 7 days DB2

I have no experience working with DB2 before and I'm kind of stuck in something. I'm working on a project in SSIS reading from DB2 where I write into a flat file. I need to run the process weekly and get data from past 7 days.
My query works this way:
Select * From Table
Where ServiceDate >= 2200624 - 7
The above query brings data from the past 7 days, but this query don't work for me since I need to execute this process weekly. I need something like this:
Select * From Table
Where ServiceDate >= DATE(CURRENT_DATE - 7 DAY)
The second query throws an error, is there any other way to achieve this? I'm using ODBC source and I was thinking to use a dynamic query in SSIS but I'm not sure how this works in ODBC source, any suggestions or help will be appreciated.
EDIT:
This tables were created a long time ago, so I don't have any information about the data type of these tables.
The actual date 2200624 correspond to 20200624. This is the way that my date shows in the table.
Thanks in advance
For ServiceDate as YYYYMMDD INT:
Select * From Table
Where ServiceDate >= INT(TO_CHAR(CURRENT_DATE - 7 DAY, 'YYYYMMDD'));
If ServiceDate is CHAR(7) or equivalent, and if value 2200624 corresponds to YYYYMMDD date 20200624 as per your edited question, then the following examples might help.
It assumes ServiceDate values beginning with first character 1 are in the 20th century (19xx years), and dates with first character 2 are in the 21st century.
SELECT ... FROM ... WHERE ( TO_DATE(CASE SUBSTR(ServiceDate,1,1) WHEN '1' THEN '19'||SUBSTR(ServiceDate,2,6) WHEN '2' THEN '20'||SUBSTR(ServiceDate,2,6) END,'YYYYMMDD')) >= CURRENT DATE - 7 DAYS
This will perform badly, so don't use that!
An alternative that will perform better is to convert CURRENT DATE - 7 DAYS into a number that matches your storage-format like this:
...WHERE ServiceDate >= '2'||substr(TO_CHAR(CURRENT_DATE - 7 DAY, 'YYYYMMDD'),2,6)
and if ServiceDate is INTEGER column datatype then:
...WHERE ServiceDate >= int('2'||substr(TO_CHAR(CURRENT_DATE - 7 DAY, 'YYYYMMDD'),2,6))
Always state your Db2-server platform (Z/OS, i-series, Linux/Unix/Windows) when asking for help with Db2, because the answer may be different depending on the platform + version of your Db2-server.

SQL Query to get data between two weeks?

I have a week column with week numbers as w0, w1, w2.... I am trying to get last last six weeks data. Here's the sql query I am using.
SELECT * FROM week
WHERE uid = '9df984da-4318-1035-9589-493e89385fad'
AND report_week BETWEEN `'w52' AND 'w5'`;
'w52' is essentially week 52 in December 2015 and 'w5' is Jan 2016. The 'between' seems to not work. Whats the best way to get data from the above two weeks?
Here's the CREATE TABLE statement:
CREATE TABLE `week` (`uid` VARCHAR(255) DEFAULT '' NOT NULL,
`report_week` VARCHAR(7) NOT NULL,
`report_files_active` BIGINT DEFAULT NULL);
Essentially this table is getting populated from other table which has date column. It uses dates from other table and summarizes weekly data into this.
Any help is appreciated.
Refer to this SO Discussion which details the reasons for a problem similar to yours.
BETWEEN 'a' and 'b' actually matches to columnValue >='a' and columnValue <= 'b'
In your case w52 is greater than w5 due to lexicographic ordering of Strings - this means that the BETWEEN clause will never return a true (think about it as equivalent to saying BETWEEN 10 and 1 instead of BETWEEN 1 and 10.
Edit to my response:
Refrain from storing the week value as a string. Instead here are a couple of approaches in order of their preference:
Have a timestamp column. You can easily then use MySQL query
facilities to extract the week information out of this. For a
reference see this post.
Maintain two columns - YEAR, WEEKNO where YEAR will store values
like 2015, 2016 etc and WEEKNO will store the week number.
This way you can query data for any week in any year.
please show me table structure and DB name because it different for other, if it is any timestamp then we can use BETWEEN 'systemdate' AND 'systemdate-6'

Formatting a date value in Reporting Services

I am a bit rusty and would be very grateful if you could help. I am using Reporting Services. I am using T-SQL. The date_ordered field mentioned below is data type varchar.
I have a simple report that gives the date_ordered value. Unfortunately, when I ORDER BY date_ordered DESC, it sorts the date by the numerical value of the day, so 31-Oct-14 appears first and 01-Apr-13 last.
I would like the report to show most recent dates first and end with the last date ordered.
I'm sure it's very obvious, but I can't see it.
With many thanks.
you just have to convert your date to a datetime format in tsql. then when you sort it it works as expected.
Select CONVERT (datetime, '24-04-2012', 105 as date) as date,
[date dispatched] from Orders order by 1
see How convert string to date T-SQL? and https://msdn.microsoft.com/en-us/library/ms187928.aspx

mySQL format number output , thousands separator

I have a mySQL query which is outputting decimal fields with a comma.
SELECT Metals.Metal, FORMAT(Fixes.GBPam, 3) AS AM, FORMAT(Fixes.GBPpm, 3) AS PM,
DATE_FORMAT(Fixes.DateTime, '%d-%m-%y') AS Date
FROM Fixes, Metals
WHERE Metals.Id = Fixes.Metals_Id
Fields GBPam and GBPpm are both of type decimal(10,5)
Now I want columns AM and PM to be formatted to 3 decimal places in my sql query - Correct
I want values in the thousands to be formatted as xxxx.xxx and not x,xxx.xxx - Incorrect
Example output from mysql query:
Metal AM PM Date
Gold 1,081.334 NULL 11-09-12
Silver 21.009 NULL 10-09-12
Platinum 995.650 NULL 11-09-12
Palladium 416.700 NULL 11-09-12
Can you see that output for Gold AM is 1,081.334? How can I get it to output 1081.334?
This is a pain in the ass for me because I have to then muck about in PHP to remove the comma. I would prefer to just get mysql to format it correctly.
Just use ROUND, this is a numeric function. FORMAT is a string function
ROUND(Fixes.GBPam, 3)
you can use replace command for this purpose.
REPLACE(Fixes.GBPam,',','')
EDIT:
With respect to your question you could do something like this:
SELECT Metals.Metal, ROUND(REPLACE(Fixes.GBPam,',',''),3) AS AM,
ROUND(REPLACE(Fixes.GBPpm,',',''),3) AS PM,
DATE_FORMAT(Fixes.DateTime, '%d-%m-%y') AS Date
FROM Fixes, Metals
WHERE Metals.Id = Fixes.Metals_Id
Use replace function. Whether the field is integer or varchar, it will work.
select replace(Fixes.GBPam,',','.');