通过整个查询保存SQL列转换

时间:2018-03-28 22:40:28

标签: sql sql-server sql-server-2008 sql-view

场合

我正在尝试使用列名称来构造查询:TxnDate(TransactionDate),类型为INT。典型日期如下所示:YYYYMMDD,因此2018020920171025为例。我无法改变这个事实,否则很多事情都会破裂。不幸的是,它陷入了这种愚蠢的格式。

但是,它仅对我有用,因为数据类型DATE,所以我必须首先以迂回方式转换它:CONVERT(DATE, CONVERT(char(8), TransactionDate))

为了使事情进一步复杂化,由于各种原因,某些日期为空,负或零。因此,为了使其成为可用的形式,我需要检查以确保它可以转换:

CASE WHEN ISDATE(TxnDate)=1 THEN CONVERT(DATE, CONVERT(CHAR(8),TxnDate)) END

日期数据不佳的记录对我没用。

问题是我需要检查然后在WHERE语句中的许多不同位置进行转换。这使我的查询膨胀到略微荒谬的比例。我希望以更清洁,更简洁的方式表达一些智慧。

我考虑的内容

我不愿意在架构中添加内容,但如果是更好的选择,我会这样做:

1)创建一个视图,为我演示,我可以从中查询,代替表格,如下所示:Is it possible to change the datatype of a column in a view?我不偏袒于此,因为尝试时可能会出现问题施放,这使整个目的无效。

2)创建一个用户定义的函数,在调用时只运行CASE表达式。

3)我为变量尝试了许多不同的别名变体,并以许多不同的方式使用AS表达式尝试仅在一个地方定义它,但无济于事。这可能是可能的,但我无法通过自己的努力或通过互联网搜索找到它。

同样,我很欣赏这方面的任何智慧,我是SQL新手,所以如果有明显的解决方案或重复的问题,请指出。此外,如果你觉得这个问题出了问题,我宁愿你在投票前告诉我什么是不正确的,这样我就有机会改进和学习。

谢谢

1 个答案:

答案 0 :(得分:0)

您可以使用此测试结尾处给出的查询。我必须生成与您的规范相匹配的虚拟数据来执行测试,但您只需要生成所需日期列(Transaction_Date)的SQL。

create table #test1 (
    TxnDt int
)
go

insert #test1 values(20180328)  -- March 28, 2018
insert #test1 values(20170220)  -- Feb 20, 2017
insert #test1 values(20161201)  -- Dec 1, 2016
insert #test1 values(2016)      -- bad data 
insert #test1 values(1)         -- data
go 

select distinct * from #test1
go 

TxnDt
1
2016
20161201
20170220
20180328

- 假设正确的数据将以yyyymmdd的形式存在,您可以运行以下SQL将其转换为日期类型

select *
from 
(
    select distinct TxnDt 
        , case when len(cast(TxnDt as char(8))) = 8 
            then convert(date,substring(cast(TxnDt as char(8)),5,2) + '/' + substring(cast(TxnDt as char(8)),7,2) + '/' + substring(cast(TxnDt as char(8)),1,4))    
        end as Transaction_Date
    --  , case when len(substring(cast(TxnDt as char(8)),5,2) + '/' + substring(cast(TxnDt as char(8)),7,2) + '/' + substring(cast(TxnDt as char(8)),1,4)) = 10 then TxnDt end
    --  , convert(date,substring(cast(TxnDt as char(8)),5,2) + '/' + substring(cast(TxnDt as char(8)),7,2) + '/' + substring(cast(TxnDt as char(8)),1,4))   TransDate
--into #test2
    from #test1
) main
where main.Transaction_Date is not null
go

TxnDt   Transaction_Date
20161201    2016-12-01
20170220    2017-02-20
20180328    2018-03-28