【问题标题】:Creating a decade for a Datestamp which only returns the last digit of the year为仅返回年份的最后一位数字的 Datestamp 创建十年
【发布时间】:2011-07-18 17:01:35
【问题描述】:

所以我正在尝试在一种卡上创建一个到期日期列。到期日期在条形码中编码为 ddmmy 格式的 5 数字字符串。问题是卡只返回年份的最后一位,我需要整个日期。例如,如果条形码中与日期相对应的部分是 19052,那么到期日期可能是 1992 年 5 月 19 日、2002 年 5 月 19 日或 2012 年 5 月 19 日。

我的解决方法是提取在卡上运行测试日期的已知年份。我要做的是创建一个 If 语句,说明 IF 到期日期的最后一位数字 = batch.StartTime 年份的最后一位数字 THEN 到期年份 = batch.StartTime 年份。 ELSE IF 到期年份的最后一位数字 = 0 和批次的最后一位数字。StartTime 年份 = 9 THEN 到期年份 = 批次的前 3 位数字。StartTime 年份 + 到期日期的最后一位数字 + 10(下一个十年)。 ELSE 到期年份 = 批次的前 3 位数字。StartTime 年份 + 到期日期的最后一位数字。

问题是我的 IF 语句不起作用。我不断收到 IF 错误的语法错误。此外,如果我尝试分别查看每个条件的结果,它会告诉我它无法将日期和月份(之间带有“/”)转换为 INT,即使我将它们声明为字符。代码如下:

SELECT

(CAST(SUBSTRING(tbl_CardIdentification.CardId, 11,2) + '/' + --this is the day
SUBSTRING(tbl_CardIdentification.CardId, 13,2) + '/' AS CHAR(6)) + -- this is the month

(IF 
(SUBSTRING(tbl_CardIdentification.CardId, 15,1) =
(SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 4,1)))
SELECT SUBSTRING(CAST(DATEPART(YY, tbl_Batch.Start) AS CHAR(4)),1,4)

ELSE IF  
(CAST(SUBSTRING(tbl_CardIdentification.CardId, 15,1) AS INT)) = 0 AND
(CAST(SUBSTRING(CAST(DATEPART(YY, tbl_Batch.Start) AS CHAR(4)), 4,1) AS INT)) = 9
SELECT (CAST((SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1,3) +
SUBSTRING(tbl_CardIdentification.CardId, 15,1)) AS INT) + 10)

ELSE SELECT
(SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1,3) +
SUBSTRING(tbl_CardIdentification.CardId, 15,1))

AS Card_Expiration

FROM

tbl_LoadProcess

JOIN tbl_Batch ON
tbl_Batch.LoadProcessSid = tbl_LoadProcess.LoadProcessSid

JOIN tbl_CardIdentification ON
tbl_CardIdentification.LoadProcessSid = tbl_LoadProcess.LoadProcessSid

【问题讨论】:

    标签: sql-server date join if-statement


    【解决方案1】:

    SELECT 语句中不允许使用 IF。您可以在语句中将其替换为 CASE。它看起来像这样

    SELECT
    
    (CAST(SUBSTRING(tbl_CardIdentification.CardId, 11,2) + '/' + --this is the day
    SUBSTRING(tbl_CardIdentification.CardId, 13,2) + '/' AS CHAR(6)) + -- this is the month
    
    CASE
    WHEN
      (SUBSTRING(tbl_CardIdentification.CardId, 15,1) =
      (SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 4,1)))
    THEN
      SUBSTRING(CAST(DATEPART(YY, tbl_Batch.Start) AS CHAR(4)),1,4)
    
    WHEN
      (CAST(SUBSTRING(tbl_CardIdentification.CardId, 15,1) AS INT)) = 0 AND
      (CAST(SUBSTRING(CAST(DATEPART(YY, tbl_Batch.Start) AS CHAR(4)), 4,1) AS INT)) = 9
    THEN
      (CAST((SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1,3) +
      SUBSTRING(tbl_CardIdentification.CardId, 15,1)) AS INT) + 10)
    
    ELSE
      (SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1,3) +
      SUBSTRING(tbl_CardIdentification.CardId, 15,1))
    END
    
    AS Card_Expiration
    
    FROM
    
    tbl_LoadProcess
    
    JOIN tbl_Batch ON
    tbl_Batch.LoadProcessSid = tbl_LoadProcess.LoadProcessSid
    
    JOIN tbl_CardIdentification ON
    tbl_CardIdentification.LoadProcessSid = tbl_LoadProcess.LoadProcessSid
    

    CASE 运算符包括其他关键字,包括 WHEN、THEN、ELSE 和 END。另外,请注意,您的 IF 中的 SELECT 关键字也不需要。

    【讨论】:

    • 这适用于我的条件,但是我仍然收到错误消息,指出无法将日期和月份转换为 INT:“消息 245,级别 16,状态 1,行 1 转换时转换失败将 varchar 值 '01/08/' 转换为数据类型 int。"
    【解决方案2】:

    我还没有实际测试过,因此可能存在括号问题或其他小语法问题,但您基本上需要将 IF 语句转换为 CASE WHEN。要解决转换为 INT 的问题,请将整个语句包装在 CAST 中,例如:

    CAST(CASE
      WHEN 
        SUBSTRING(tbl_CardIdentification.CardId, 15,1) = 
        RIGHT(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1)
      THEN
        CAST(DATEPART(YY, tbl_Batch.Start) AS CHAR(4))
    
      WHEN
        CAST(SUBSTRING(tbl_CardIdentification.CardId, 15,1) AS INT) = 0
        AND RIGHT(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1) = '9'
    
      THEN
        CAST(DATEADD(yy, 11, tbl__Batch.Start) AS CHAR(4))
    
      ELSE
        SUBSTRING(CAST(DATEPART(YY, tbl__Batch.Start) AS CHAR(4)), 1,3) +
        SUBSTRING(tbl_CardIdentification.CardId, 15,1)
    
      END AS CHAR(4)) AS Card_Expiration
    

    我进行了许多其他简化修改,其目的是消除代码中一些不必要的混乱/复杂性,从而更容易看到它在做什么和调试问题。具体来说:

    • 将最右边的字符拉回转换为 RIGHT 的 SUBSTRING
    • 将删除的整个字符串拉回的SUBSTRING
    • 将 CAST 转换为 INT 到字符串比较
    • 在最后一种情况下,不是在卡日期上加 10,而是在批次日期上加 11。 (简单得多,结果相同,对吧?)

    祝你好运!

    -迈克尔

    【讨论】:

      【解决方案3】:

      这应该对你有用,一个更简单的解决方案,只需替换适当的名称。我正在返回月份、日期和年份以及完整日期(这可能是您感兴趣的):

      DECLARE @StartDate DATETIME
      DECLARE @InputDate NCHAR(5)
      
      SELECT @StartDate = '02/01/2000'
      SELECT @InputDate = '19052'
      
      SELECT LEFT(@InputDate, 2) AS MyDay, SUBSTRING(@InputDate, 3,2) AS MyMonth,
          LEFT(DATEPART(YEAR, @StartDATE),LEN(DATEPART(YEAR, @StartDate))-1) + RIGHT(@InputDate,1) AS MyYear, 
          CAST(SUBSTRING(@InputDate,3,2) + '/'+LEFT(@InputDate, 2) + '/'+
              LEFT(DATEPART(YEAR, @StartDATE),LEN(DATEPART(YEAR, @StartDate))-1) + RIGHT(@InputDate,1) AS DATETIME) AS FullDate
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-06
        • 1970-01-01
        相关资源
        最近更新 更多