简体   繁体   中英

How to convert text to date entered as a date in sql?

Data type is TEXT and entered as '20/11/2017' and when using MAX or MIN it ignores the month. I am trying to convert it into a date format for month to be considered as well.

CAST AND CONVERT do not seem to work as the following error returns

Msg 241, Level 16, State 1, Line 13
Conversion failed when converting date and/or time from character string.

Code:

SELECT     
    user_id, 
    record_id
    --CAST(onSale AS date) AS onSale
    --CONVERT(DATE, onSale) AS onSale, 
    --CONVERT(DATE, OffSale) AS OffSale
FROM (SELECT  user_id, 
             record_id,
             (SELECT MAX(value) AS Expr1
             FROM      UPLOADS.LINES AS SUH WITH (NoLock, ReadUncommitted)
             WHERE  (field_id = 4782) AND (record_id = UR.record_id)) AS onSale,
             (SELECT MAX(value) AS Expr1
             FROM      UPLOADS.LINES AS SUH WITH (NoLock, ReadUncommitted)
             WHERE  (field_id = 4783) AND (record_id = UR.record_id)) AS OffSale
        FROM   UPLOADS.RECORDS AS UR WITH (NoLock, ReadUncommitted)
        WHERE      (module_id = 18)) AS DATA;

The end result would essentially be the MAX or MIN date with all three components being date,month and year. So if the user has entered two dates being 17/05/2018 and 17/04/2018 then the first should be shown if MAX is used.

You can use a format code when using CONVERT, and you can even use TRY_CONVERT to prevent errors from invalid dates. I also improved your code to make it simpler and more efficient.

SELECT  [user_id], 
        record_id,
        MAX(CASE WHEN SUH.field_id = 4782 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS onSale,
        MAX(CASE WHEN SUH.field_id = 4783 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS OffSale
FROM  UPLOADS.RECORDS AS UR 
JOIN  UPLOADS.LINES AS SUH ON SUH.record_id = UR.record_id
WHERE  module_id = 18
GROUP BY [user_id], 
        record_id;

This is a slight improvement on Luis's answer in terms of the SQL:

SELECT ur.[user_id], ur.record_id,
       MAX(CASE WHEN SUH.field_id = 4782 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS onSale,
       MAX(CASE WHEN SUH.field_id = 4783 THEN TRY_CONVERT( DATE, SUH.value, 103) END) AS OffSale
FROM  UPLOADS.RECORDS UR LEFT JOIN
      UPLOADS.LINES AS SUH
      ON SUH.record_id = UR.record_id AND
         SUH.field_id IN (4782, 4783)
WHERE ur.module_id = 18
GROUP BY ur.[user_id], ur.record_id;

That said, your problem is that your data is not in the format you think it is. Hence, the problem with type conversions. As @marc_s says in a comment, you should be using SQL native and appropriate types which in this case is DATE . And you certainly should not be using deprecated types, such as TEXT (unless you really just mean VARCHAR() and don't realize that there is a deprecated TEXT type). If you are storing values in strings (because there are different types), you should use the standard format, either YYYYMMDD or YYYY-MM-DD.

You can find these values by running:

select suh.value
from uploads.lines suh
where suh.field_id in (4782, 4783) and
      try_convert(date, suh.value, 103) is null and
      suh.value is not null;

This can help you fix your data.

After you have fixed your data, you can also fix the type:

update uploads.lines
    set suh.value = convert(varchar(255), convert(date, suh.value, 103), 112);  -- this will convert the value to the default date format

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM