Okay, so I have kind of a weird issue... the dates in the table have been entered in as string values MMDDYYYY and I'm trying to have the displayed as MM/DD/YYYY in a report and only select the most recent date pertaining to an ID, because some ID's may have multiple dates.

Example of my table:

  ID  |  MyDate  |
------+----------+
  1   | 01302014 |
  1   | 04222014 |
  2   | 01302014 |

What I want to see when I select and insert into a temp table is this:

  ID  |   MyDate  |
------+-----------+
  1   | 4/22/2014 |
  2   | 1/30/2014 |

I know that storing dates as string values is a poor practice especially when storing them as MMDDYYYY, but does anyone have a solution to this nightmare?

EDIT

I forgot to mention that some fields might be NULL. Not sure if that makes a difference or not, but I think it does if I try to flip the dates using Right, Left, Convert.

有帮助吗?

解决方案

This question is for almost a year ago, nut probably someone can find it useful.

You need to CONVERT your string to DATE format and use a ROW_NUMBER function to window your result set.

Create table

DECLARE @tbl TABLE(Id INT, myDate VARCHAR(8))

Sample data

INSERT @tbl
SELECT 1  ,  '01302014' UNION ALL
SELECT 1  ,  '04222014' UNION ALL
SELECT 2  ,  '01302014'

Query

;WITH C AS(
    SELECT  ROW_NUMBER() OVER (PARTITION BY Id ORDER BY CONVERT(DATETIME, (SUBSTRING(myDate, 5, 4) + '.' + SUBSTRING(myDate, 1, 2) + '.' + SUBSTRING(myDate, 3, 2)), 101) DESC) AS Rn
            ,Id
            ,CAST(CONVERT(DATETIME, (SUBSTRING(myDate, 5, 4) + '.' + SUBSTRING(myDate, 1, 2) + '.' + SUBSTRING(myDate, 3, 2)), 101) AS DATE) AS myDate
    FROM @tbl
)
SELECT Id, myDate
FROM C
WHERE Rn = 1

SQLFiddle Demo

其他提示

Using a CONVERT like the following code snippet will work on any SQL Server regardless of language and/or locale configuration.

DECLARE @OldDate varchar(8); 
SELECT @OldDate = '04252012';

SELECT CONVERT(datetime, substring(@OldDate,5,4) + '-' + substring(@OldDate,1,2) + '-' + substring(@OldDate,3,2) + 'T00:00:00')

You could try this:

convert(date,SUBSTRING (MyDate,1,2)+'/'+SUBSTRING (MyDate,3,2)+'/'+SUBSTRING (MyDate,5,4),101)
Select CONVERT(datetime,RIGHT('01302014',4) +
                       LEFT('01302014',2) +
                       SUBSTRING('01302014',3,2))

'2014-01-30 00:00:00.000'

;with Cte as (Select Id,CONVERT(datetime,RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)) as sDate, C=ROW_NUMBER()
over(PARTITION By Id Order by MyDate desc)
From #Temp)

select * 
from Cte
where C=1

First do a conversion to a datetime datatype, then convert it to a format you wish to:

select id, convert(varchar, max(convert(datetime,right(mydate, 4)+left(mydate,4))), 101)
from #t
group by id

Although I can't understand why would it not suffice to just convert it do datetime and leave the formatting where it belongs, to the client.

Select id,convert(varchar(11),cast(dateValue as Date),101)
From
(
Select id,MAX(cast(MyDate As Date)) as dateValue
From tableName
Group By id
) t

The simplest solution is mySQL str_to_date() function.

STR_TO_DATE(`MyDate`, '%m%d%Y')

This will convert it to a DATETIME which you then format as required

DATE_FORMAT(STR_TO_DATE(`MyDate`, '%m%d%Y'), '%c/%e/%Y')

Complete Query:

Select ID, Case When IsDate(RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)) = 1 
THEN Convert(varchar(10), Convert(datetime, RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)), 101) 
        ELSE Null END AS MyDate FROM YourTable a where Case When IsDate(RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)) = 1 
        THEN Convert(varchar(10), Convert(datetime,  RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)), 101) 
        ELSE Null END = (Select Max(Case When IsDate(RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)) = 1 
        THEN Convert(varchar(10), Convert(datetime, RIGHT(MyDate,4)+LEFT(MyDate,2)+SUBSTRING(MyDate,3,2)), 101) 
        ELSE Null END)
        FROM YourTable b
        Where a.ID = b.ID
        )

This is a modified version from Dimitris Kalaitzis' answer.

First, you will need to convert your MyDate into String. The data for example (01302014) is not treated as a string and the leading zero will be removed when you convert it. Therefore, use CAST to make MyDate as a String and add a leading 0 to it. Then you find the right 8 characters so to get rid of the leading zero for months from Oct to Dec.

Here is the code that should work for you:

CONVERT(Date, SUBSTRING(RIGHT('0' + CAST(MyDate AS VARCHAR(10)), 8), 1, 2) + '/' + SUBSTRING(RIGHT('0' + CAST(MyDate AS VARCHAR(10)), 8), 3, 2) + '/' + SUBSTRING(RIGHT('0' + CAST(MyDate AS VARCHAR(10)), 8), 5, 4), 101)

Hope this helps.

You first have to add the slashes to be able to convert it to a date, use STUFF Then convert it to a DATE and select the MAX group by ID

Query:

SELECT ID, FORMAT(MAX(CONVERT(DATE,STUFF(STUFF(MyDate,3,0,'/'),6,0,'/'))),'MM/dd/yyyy') AS MyDate FROM TableName
GROUP BY ID
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top