【问题标题】:SQL, Case with Like inside of the whereSQL,在 where 中带有 Like 的大小写
【发布时间】:2016-05-12 09:51:39
【问题描述】:

有人可以帮助我吗? 我有一个具有这种结构的字段:2,3,4,5,6,0,1 他们是星期几,如果今天是一周中的最后一个交货日,我必须找出什么时候,问题是这样的:

例如,今天是第 3 天,通过以下查询,我可以选择所有以数字 3 结尾的人,但如果我有人具有这种​​结构:3,0,1 或 3,1 或 3,0我不明白。

declare @today int
set @today=DATEPART(dw,GETDATE())-2
print @today
select cast (cfv.value as VARCHAR)
from CompanyFieldvalues cfv
join CompanyFields cf on cf.companyFieldId=cfv.companyFieldId
where cf.name='NextDeliveryDates' and cfv.companyId in(
select cfv.companyId
from CompanyFieldvalues cfv
join Companies c on c.companyId=cfv.companyId
where cfv.value='Retailer' and c.status=1)
and (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' + cast (@today as VARCHAR))

为了解决这个问题,我很难介绍一个案例,所以我的查询将是这个:

declare @today int
set @today=DATEPART(dw,GETDATE())-2
print @today
select cast (cfv.value as VARCHAR)
from CompanyFieldvalues cfv
join CompanyFields cf on cf.companyFieldId=cfv.companyFieldId
where cf.name='NextDeliveryDates' and cfv.companyId in(
select cfv.companyId
from CompanyFieldvalues cfv
join Companies c on c.companyId=cfv.companyId
where cfv.value='Retailer' and c.status=1)
and (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' + cast (@today as VARCHAR))  and  case
        when (@today != 0 or @today!=1) 
        then (cfv.value not like '%,0' or cfv.value not like '%,1')

但在这种情况下,我会收到以下错误消息:

Msg 156, Level 15, State 1, Line 14 关键字附近的语法错误 '不是'。

我确定我犯了一些愚蠢的错误,但我不明白:S

请帮忙! 非常感谢

【问题讨论】:

  • 标记使用的 dbms,那里有很多特定于产品的 SQL...
  • 我的意思是标记您正在使用的 dbms 产品。 (例如 SQL Server,或 Oracle,或 Sybase 或其他。)那么你的问题会得到更好的关注,你会得到更好的答案,更快!

标签: sql database datetime case ssms-2012


【解决方案1】:

使用 CASE 语句应如下所示:

declare @today int
set @today=DATEPART(dw,GETDATE())-2
print @today

select cfv.value
from CompanyFieldvalues cfv
join CompanyFields cf on cf.companyFieldId=cfv.companyFieldId
where cf.name='NextDeliveryDates' and cfv.companyId in(
select cfv.companyId
from CompanyFieldvalues cfv
join Companies c on c.companyId=cfv.companyId
where cfv.value='Retailer' and c.status=1)

and

CASE
    WHEN (@today !=0 or @today!=1) THEN
        (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' + cast    (@today as VARCHAR) 
        or cfv.value like '%' + cast (@today as VARCHAR)+',0'
        or cfv.value like '%' + cast (@today as VARCHAR)+',0,1'
        or cfv.value like '%' + cast (@today as VARCHAR)+',1')
    ELSE
        (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' +  cast  (@today as VARCHAR))
END = 1

或 *******************************************

 CASE
    WHEN ((@today !=0 or @today!=1) AND (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' + cast    (@today as VARCHAR) 
        or cfv.value like '%' + cast (@today as VARCHAR)+',0'
        or cfv.value like '%' + cast (@today as VARCHAR)+',0,1'
        or cfv.value like '%' + cast (@today as VARCHAR)+',1'))
    THEN 1
    WHEN (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' +  cast  (@today as VARCHAR)) THEN 1
    ELSE 0
END = 1

但表达式(@today !=0 或 @today!=1)始终为 true。也许你应该找到另一个有意义的条件

【讨论】:

  • 嗨 Patricia,非常感谢答案,不(@today !=0 或 @today!=1)并非每次都是正确的,因为我将日期声明为:set @today=DATEPART( dw,GETDATE())-2 这是因为在后面我有一个 C# 代码,它以不同的方式管理日期;)我会尝试你的建议,我会告诉你;)
  • 是的,总是如此。如果你否认它,你会得到这样的结果:今天 == 0 和今天 == 1,显然它总是错误的。问题不在于 CASE 语句的语法。没有得到预期答案的原因是逻辑错误。
  • 嗨帕特里夏,是的,你是对的,我只是尝试一下:S,我该怎么做?但是为什么今天 == 0 和今天 == 1 总是错误的?如果我今天模拟这个声明 int set today=DATEPART(dw,GETDATE())-5 print today -----我有一个 today=0 那么为什么应该是假的?我该如何解决这个问题?哦,无论如何,我不得不使用你给我的 2 个选项,第一个我不知道为什么会给我带来问题。无论如何,我刚刚用我当前的查询发布了一个新的答案,当我模拟一个 0 案例时有什么问题
  • 一个值不能同时等于 0 和等于 1。要么是其中之一,要么没有,但不能同时是两者。对我来说,我给你的第二个建议在语法方面是有效的。您能告诉我表格的确切内容以及您要检索的内容吗?
  • 嗨,Patricia,是的,当然...我会发布一个包含所有信息的答案,我会称之为 UPDATE,但请给我几分钟 ;) 非常感谢
【解决方案2】:

您可以将 CASE 语句替换为逻辑表达式:

(((@today != 0 or @today!=1) AND (cfv.value not like '%,0' or cfv.value not like '%,1')) OR NOT (@today != 0 or @today!=1))

所以你的查询会变成:

declare @today int
set @today=DATEPART(dw,GETDATE())-2
print @today
select cast (cfv.value as VARCHAR) from CompanyFieldvalues cfv
    join CompanyFields cf on cf.companyFieldId=cfv.companyFieldId
    where cf.name='NextDeliveryDates' and cfv.companyId in(
        select cfv.companyId
            from CompanyFieldvalues cfv
            join Companies c on c.companyId=cfv.companyId
            where cfv.value='Retailer' and c.status=1) 
            and (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value     like '%' + cast (@today as VARCHAR)) 
            and  (((@today != 0 or @today!=1) AND (cfv.value not like '%,0' or cfv.value not like '%,1')) OR NOT (@today != 0 or @today!=1))

【讨论】:

  • 诚然,您只是从 OP 中复制了此内容,但这部分始终是正确的; (@today != 0 or @today!=1) (除非 @today 为 NULL)。此外,符号&&||的使用应替换为关键字ANDOR
  • 它仍然不是在所有情况下都有效,如果值以 3 结束,例如当前日期,它可以工作,但没有选择在数据库中我有值 3,0,1 的时间。我将添加更多详细信息的答案
【解决方案3】:

帕特里夏更新:

这是我的表,它只有一行的值代表一个人的最后交货日,问题是他们有这样的结构:2,3,4,5,6,0,1

3,0,1
0,1
3,0
5,6
5,5
5
3

我需要知道这个人的最后一个交货日是否是今天(0 和 1 每次都在最后,但实际上它们不是最后一个交货日,而是第一个和第二个交货日)。

我想我必须为 0 和 1 创建 2 个单独的案例,但我没有得到它们:S 这是我实际拥有的:

declare @today int
set @today=DATEPART(dw,GETDATE())-2 /*-2 because the date are managed from a c# code so I need in this way to have the day in the format Monday=0, etc*/
print @today
select cfv.value
from CompanyFieldvalues cfv
join CompanyFields cf on cf.companyFieldId=cfv.companyFieldId
where cf.name='NextDeliveryDates' and cfv.companyId in(
select cfv.companyId
from CompanyFieldvalues cfv
join Companies c on c.companyId=cfv.companyId
where cfv.value='Retailer' and c.status=1)
and
 CASE
    WHEN ((@today !=0 or @today!=1) AND (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' + cast    (@today as VARCHAR) 
    or cfv.value like '%' + cast (@today as VARCHAR)+',0'
    or cfv.value like '%' + cast (@today as VARCHAR)+',0,1'
    or cfv.value like '%' + cast (@today as VARCHAR)+',1'))
    then 1
    WHEN (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' +  cast  (@today as VARCHAR)) THEN 1
    ELSE 0
END = 1

正如你所说,我在第 0 天或第 1 天时每次都有问题。 如果是第 0 天,我必须只选择 value=0,第 1 天我必须选择 value=1 或 value=0,1 的时间,所以我想我需要修改第二个条件:

WHEN (cfv.value like '%,' + cast (@today as VARCHAR) or cfv.value like '%' +  cast  (@today as VARCHAR)) THEN 1

创建两个不同的不是吗?

【讨论】:

  • 你仍然有(@today !=0 or @today!=1) 这是总是 TRUE...如果@today = 0 那么你有(0 != 0) OR (0 != 1) => (FALSE) OR (TRUE) => TRUE。唯一不正确的情况是 @todayNULL
  • 但为什么它总是正确的?我不明白:S 我已经声明了@today=DATEPART(dw,GETDATE())-2 所以当它是星期一时@today=0!为什么从不进入这种情况?我该如何解决?
【解决方案4】:

如果我是你并且我很了解你打算做什么,我会按照以下方式实施。我会定义一个分割你的字符串的函数:

create function dbo.SplitString 
(
    @str nvarchar(max), 
    @separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
    select 
        cast(1 as bigint), 
        cast(1 as bigint), 
        charindex(@separator, @str)
    union all
    select
        p + 1, 
        b + 1, 
        charindex(@separator, @str, b + 1)
    from tokens
    where b > 0
)
select
    p-1 ItemIndex,
    substring(
        @str, 
        a, 
        case 
        when b > 0 then b-a 
        ELSE LEN(@str) end) 
    AS Item
from tokens
);

GO

然后我会使用以下条件:

AND where not exists(select * from dbo.SplitString(cfv.value, ',') where    CAST(Item AS INT) > @today )   

我在您提供给我的样品上进行了测试,效果很好。所以对于以下输入:

5 
5 
3,4
5 
5 
5 
3,0,1 
3,0 
5 
3

返回:

3
3,0,1
3,0

【讨论】:

  • 哦,完美,如果您看到我的评论,我会以另一种方式解决,但我认为您的效率更高;)非常感谢hhh
猜你喜欢
  • 2017-01-23
  • 1970-01-01
  • 2013-09-22
  • 2022-01-21
  • 2014-09-20
  • 2013-08-01
  • 2010-09-17
  • 2014-08-19
  • 1970-01-01
相关资源
最近更新 更多