如何跳过TSQL查询中具有NULL值的值?

时间:2018-03-27 09:39:22

标签: sql sql-server sql-server-2008 tsql

我有这个相当复杂的查询:

CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo

我需要从' 2017年12月31日' 转换 v.RefPeriodOd v.RefPeriodDo 格式' 31/12 / 2017'

是的我知道将DateTime保存为字符串(varchar)是个坏主意,但是现在正在使用该应用程序,所以我现在无法真正做QA并重构我的表。

我正在使用这句话:

CHARINDEX('-', RefPeriodDo, 0) != 0

但问题是, v.RefPeriodOd v.RefPeriodDo 可以包含NULL值以及格式的值:' 31 /二千零十七分之十二'

如果我删除了这个条件:

TSQL

我收到此错误:

  

将nvarchar数据类型转换为日期时间数据类型   导致了超出范围的价值。

如何在查询中添加一些条件?

IF语句是否存在于for(i in 1:nrow(df)){ for(j in 1:(ncol(df)-1)){ df[i, j] <- ifelse(df[i, ncol(df)] > 9, 1, df[i, j]) df[i, ncol(df)] <- rowSums(df[i, 1:(ncol(df)-1)]) } }

5 个答案:

答案 0 :(得分:5)

更改

CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd

CASE 
    WHEN CHARINDEX('-', RefPeriodDo, 0) != 0 
    THEN CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) 
END as RefPeriodOd

然后移除WHERE

中的过滤器

&#34; IF的&#34;如果在CASE语句中,则用SELECT子句表示,最常见的语法如下:

CASE
    WHEN 1stCondition THEN 1stValue
    WHEN 2ndCondition THEN 2ndValue
    ELSE DefaultValue -- Else is optional
END

条件按顺序进行评估,如果未发出ELSE,则会返回NULL

答案 1 :(得分:3)

尝试添加以下where

WHERE (v.RefPeriodOd is not null and v.RefPeriodOd <> '')
  AND (v.RefPeriodDo is not null and v.RefPeriodDo <> '')

答案 2 :(得分:3)

注意:

  • 您不能将条件放在WHERE子句中。过滤不一定在SELECT
  • 中的表达式之前
  • 您应该始终在SQL Server中包含字符串的长度。

处理此问题的正确方法是try_convert()

TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
TRY_CONVERT(varchar(255), TRY_CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
自SQL Server 2012起,

TRY_CONVERT()可用。在此之前,您需要使用CASE来避免转换错误。

在我看来,过滤条件应为:

RefPeriodDo LIKE '%-%'

我认为这更容易编写和阅读。

答案 3 :(得分:1)

试试这个:

SELECT distinct 
    v.KodQ, v.DodPeriodika, 
    v.GodGP, v.Periodika as Period, 
    k.Oblast, k.KratokNazivSI, 
    k.NazivSI, k.Periodika, 
    v.rKod, r.Naziv, 
    v.rDatum,
    v.IT, v.Primerok, v.BrojIE, 
    CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodOd), 103) as RefPeriodOd,
    CONVERT(varchar, CONVERT(DATETIME, v.RefPeriodDo), 103) as RefPeriodDo
FROM GP.dbo.MyTable1 AS v 
INNER JOIN GP.dbo.MyTable2 as k 
ON k.KodSI = v.KodQ AND k.DodObr = v.DodPeriodika
INNER JOIN GP.dbo.MyTable3 AS r 
ON r.rKod = v.rKod
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''

使用WHERE

过滤行
WHERE v.GodGP = GodGP AND ISNULL(v.RefPeriodOd,'')<>'' AND ISNULL(v.RefPeriodDo,'')<>''

答案 4 :(得分:1)

试试这个 注意双重使用103

declare @D table (id int identity primary key, dt varchar(20));
insert into @D (dt) values (null), ('messy'), ('31-Dec-2017'), ('31/12/2017'), ('1/12/2017');
select d.dt 
     , TRY_CONVERT(DATETIME, d.dt, 103) as dt103 
     , isnull(TRY_CONVERT(varchar(20), TRY_CONVERT(DATETIME, d.dt, 103), 103), d.dt) dt103var
from @D d;

dt                   dt103                   dt103var
-------------------- ----------------------- --------------------
NULL                 NULL                    NULL
messy                NULL                    messy
31-Dec-2017          2017-12-31 00:00:00.000 31/12/2017
31/12/2017           2017-12-31 00:00:00.000 31/12/2017
1/12/2017            2017-12-01 00:00:00.000 01/12/2017