0

我需要从 2 个没有共同点的表中编译数据。

为此,我创建了一个视图来提取我需要的位,它是交叉连接的,因此我需要通过过滤日期来去除不必要的行。

但是,我发现日期有问题。

基本上,一些用户必须在他们的系统上设置美国格式,这就是日期进入数据库的方式(m/d/yyyy)。

绝大多数日期(正确)采用英国格式 ( dd/mm/yyyy)

显然,我需要所有日期都采用相同的格式,但 CONVERT 和 CAST 似乎不起作用。

因此,我想出了使用 CASE 来确定字符串长度和内容的想法。

基本上,我查找长度为 10(例如 15/01/2012)并假设它是正确的(英国)日期,除非字符 4 和 5 大于 12。

如果是 9 个字符长,那么我需要查找第一个 '/' 的位置,它告诉我是 d/mm 还是 dd/m(年份总是 4 个字符)。

最后,如果它是 8 个字符长,我认为它必须是一个不正确的(美国)日期并颠倒数字,输入零作为填充符。

但是,当我尝试运行脚本时,它给了我:

Msg 102, Level 15, State 1, Line 12
Incorrect syntax near '='.
Msg 156, Level 15, State 1, Line 16
Incorrect syntax near the keyword 'THEN'.
Msg 4145, Level 15, State 1, Line 22
An expression of non-boolean type specified in a context where a condition is expected, near 'ELSE'.
Msg 102, Level 15, State 1, Line 24
Incorrect syntax near '@Day'.
Msg 4145, Level 15, State 1, Line 29
An expression of non-boolean type specified in a context where a condition is expected, near 'END'.
Msg 156, Level 15, State 1, Line 39
Incorrect syntax near the keyword 'IF'.
Msg 102, Level 15, State 1, Line 40
Incorrect syntax near ','.
Msg 102, Level 15, State 1, Line 41
Incorrect syntax near ','.
Msg 102, Level 15, State 1, Line 46
Incorrect syntax near ','.
Msg 156, Level 15, State 1, Line 50
Incorrect syntax near the keyword 'THEN'.
Msg 102, Level 15, State 1, Line 51
Incorrect syntax near ','.
Msg 102, Level 15, State 1, Line 52
Incorrect syntax near ','.

失败的脚本部分如下,我希望有人对我需要做什么提出建议(或者实际上是一种更好的方法来整理日期)。

我想要实现的是直接从源表(mbrProject)填充新表(或视图)中的 [START_DATE] 字段,其中 ID 匹配(我已经通过选择 distinct 填充了新表中的 ID来自 mbrProject),但也尝试动态应用日期格式更改:

declare @length int,
    @Day nchar(3),
    @Month nchar(3),
    @Year nchar(5)

Update ProjectDates
SET [Start_Date] = 
(CASE
    WHEN len(mbrProject.[Start_Date]) = 8 THEN
        @Day = '0' & SUBSTRING(mbrProject.[START_DATE],3,2), @Month = '0' & SUBSTRING(mbrProject.[START_DATE],1,2), @Year = right(mbrProject.[START_DATE],5)
        @Day + @Month + @Year

    WHEN len(mbrProject.[Start_Date]) = 9 THEN
        IF charindex('/',mbrProject.[start_date]) = 2 THEN
        @Day = SUBSTRING(mbrProject.[START_DATE],3,3), @Month = '0' & SUBSTRING(mbrProject.[START_DATE],1,2), @Year = right(mbrProject.[START_DATE],5)
        ELSE @Day = '0' & SUBSTRING(mbrProject.[START_DATE],4,2), @Month = SUBSTRING(mbrProject.[START_DATE],1,3), @Year = right(mbrProject.[START_DATE],5)
        END IF
        @Day + @Month + @Year

    ELSE
        IF SUBSTRING(mbrProject.[START_DATE],4,2) > 12
            @Day = SUBSTRING(mbrProject.[START_DATE],4,3), @Month = SUBSTRING(mbrProject.[START_DATE],1,3), @Year = right(mbrProject.[START_DATE],5)
            ELSE @Day = SUBSTRING(mbrProject.[START_DATE],1,3), @Month = SUBSTRING(mbrProject.[START_DATE],4,3), @Year = right(mbrProject.[START_DATE],5)
        END IF
        @Day + @Month + @Year

    END)

Where ProjectDates.[START_DATE] = mbrProject.[START_DATE]

==================================================== ======================

** 编辑 **

好的,非常感谢 Kaf。我使用通用脚本创建了一个新的 uodate 脚本,但它又给了我一个问题。

我将从显示新脚本开始:

Update ProjectDates
SET [Start_Date] =

(
select right([Start_Date],4) +  
    case 
        when len([Start_Date])=10 then 
            substring([Start_Date],4,2) + left([Start_Date],2)

        else    right('0' + left([Start_Date],firstIndex-1),2) + 
                right('0' + substring([Start_Date],firstIndex+1,secondIndex - firstIndex-1),2) 
                end

from 
    (
    select mp.[Start_Date], charindex('/',mp.[Start_Date],1) firstIndex,
          charindex('/',mp.[Start_Date],charindex('/',mp.[Start_Date],1)+1) secondIndex

    from mbrProject mp
    join ProjectDates pd
    on mp.ID = pd.Project_ID
    )A

where ProjectDates.Project_ID = mbrProject.ID
)

发生的情况是,如果我只运行 SELECT 语句,例如:

select right([Start_Date],4)

向下

on mp.ID = pd.Project_ID
)A

这行得通。

不幸的是,虽然完整的脚本解析正确,但它返回以下错误:

Msg 4104, Level 16, State 1, Line 25
The multi-part identifier "mbrProject.ID" could not be bound.

请问有什么想法吗?

4

1 回答 1

0

试试这个通用解决方案,将不同长度的不同格式转换为 ISO 日期格式 ( yyyymmdd)。(假设仅当日期为 dd/mm/yyyy 时您有 10 个字符)一旦将字符串日期转换为 ISO 格式,将其转换为日期/日期时间类型以进行比较。

SQL小提琴在这里

--create a table for the demo.
create table T(mydate varchar(50))
insert into T (mydate, details)
values ('m/d/yyyy'),('mm/d/yyyy'),('m/dd/yyyy'),('dd/mm/yyyy')


select mydate,
       right(mydate,4) +  case when len(mydate)=10 then 
                               substring(mydate,4,2) + left(mydate,2)
              else right('0' + left(mydate,firstIndex-1),2) + 
       right('0' + substring(mydate,firstIndex+1,secondIndex - firstIndex-1),2) 
                        end ISO_format
from (
select mydate, charindex('/',mydate,1) firstIndex,
              charindex('/',mydate,charindex('/',mydate,1)+1) secondIndex
from T ) A

--Results
MYDATE      ISO_FORMAT
m/d/yyyy    yyyy0m0d
mm/d/yyyy   yyyymm0d
m/dd/yyyy   yyyy0mdd
dd/mm/yyyy  yyyymmdd
于 2013-01-14T17:09:13.000 回答