【问题标题】:SQL - Day of the week issue on selectSQL - 选择的星期几问题
【发布时间】:2016-09-07 08:39:49
【问题描述】:

我的查询有问题.... 我有一个这样的查询:

declare @today int
set @today=DATEPART(dw,GETDATE())-2
select cast (cfv.value as VARCHAR), cfv.companyId
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) + '%' */

这给了我一个这样的表格: Unique Account of a company, Delivery Days

CM001 | 2,4,1
CD04 | 3,3,4
CS7 | 2
CR001 | 4
FG076 | 3,3,5,4 JUH768 | 2,2,2
HG006 | 2
KG040 | 3,2,5

简而言之,我只是在@today 中保存了一周中实际日期的值(-2,因为使用此数据库的系统以不同的方式管理这些日子)​​,然后我只选择了公司来自两个不同表格的信息和交货天数。

我的问题是我只需要选择今天最后交货日的公司....所以如果今天是第 2 天,我可以选择最后交货日为 1,2 - 0,2 - 0,1 的公司, 2个等等……

如果您在我的代码中看到最后一行被注释,如果您添加此行,您会得到另一个结果:

CM001 | 2,4,1
CS7 | 2
JUH768 | 2,2,2
HG006 | 2
KG040 | 3,2,5

但是通过这种方式,如您所见,我选择了当天没有作为最后交货日的不同公司。

所以我计算了一个包含所有未来日期的动态表:

declare @day int
set @day=DATEPART(dw,GETDATE())-1
declare @week int
set @week=7
declare @extra table
(extraday varchar)
while (@day<@week)
begin
insert into @extra (extraday) values (@day)
set @day=@day+1
end

这给了我这个结果: Days of the week future than the current one

3 4 5 6

我尝试做出不同的加入,不同,例如,但我不会像今天那样只拥有最后交货日的公司。

你知道我该如何解决吗?或者,如果您对我该怎么做有其他想法,请告诉我。

非常感谢, 卡罗

【问题讨论】:

  • Carlo,取最后一行,去掉最后一个外卡,像这样 - and cfv.value like '%' + cast (@today as VARCHAR)。这可以确保您正在寻找字符串模式 xxx2,而不是像以前那样寻找 xx2xx。你甚至可以更具体,所以这个 - and cfv.value like '%,' + cast (@today as VARCHAR) 在第一个通配符之后添加一个逗号。
  • 嗨史蒂夫,非常感谢您的提示,这可能会有所帮助,但我的问题是数字并非每次都按顺序排列,有时您可以找到 1、4、2。在这种情况下,第 2 天位于数据库中的最后一个位置,但它不是最后一个交货日......请提供更多提示? :D
  • 好吧,您必须定义如何确定字符串中的最后交货日期。如果您可以控制它,请将其强制到可确定的位置并始终在那里寻找它。如果你给我一个移动的目标,却不给我预测它会在哪里的方法,你就不能指望我会击中它。
  • 是的,我知道出于这个原因我遇到了所有这些问题,问题是 ac# 代码根据另一个字段管理这些数据,所以这是动态的并且可以更改:S 因为这个原因我想创建一个包含所有未来一天的动态表并进行某种联接或喜欢,但从逻辑上讲,我无法将“喜欢”多对多,我不知道是否还有其他解决方案:(
  • 嗨,史蒂夫,经过一番调查,我发现了数据的结构以及它们应该是怎样的;他们习惯遵循这个顺序:2,3,4,5,6,0,1。问题是 0 和 1 在结尾而不是开头:S 有什么想法吗?

标签: sql datetime sql-like week-number weekday


【解决方案1】:

看起来您正在尝试在 WHERE 子句中实现条件逻辑,但您的操作不正确。您需要分解语句或使用动态字符串构建来创建查询并执行它。它应该看起来像这样。根据@today 的验证例程,您可能需要添加一些保护措施来防止 SQL 注入。

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

declare @nsql nvarchar(max)

set @nsql=N'
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)  


if (@today != 0 or @today!=1)
set @nsql=@nsql+N'
        and ((cfv.value not like ''%,0''  or cfv.value not like ''%,1''))'

print @nsql
--exec sp_executesql @nsql

【讨论】:

  • mmmm 我做不到 :( 但最后我用另一种方式解决了 ;) 我要发布解决方案
【解决方案2】:

看到数据结构是这样的:2,3,4,5,6,0,1,我就这样找到了部分解决办法:

   declare @today int
set @today=DATEPART(dw,GETDATE())-2-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))

如果当天以当天结束,则为最后一天;但我还是要例外: 例子: 4,5,0 2,1 等等……

解决我很难做 IF 但收到错误消息的问题,有人知道我该怎么做吗?

declare @today int
set @today=DATEPART(dw,GETDATE())-2-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 (
        if (@today != 0 or @today!=1)
            (cfv.value not like '%,0'  or cfv.value not like '%,1')
    )

这是错误:

Msg 156, Level 15, State 1, Line 14 关键字附近的语法错误 '如果'。消息 102,级别 15,状态 1,第 15 行 'cfv' 附近的语法不正确。

【讨论】:

    【解决方案3】:

    解决方案(也许不是最好的,但它正在工作;如果没有让我知道请告诉我: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*/
    declare @case as CHAR (5)
    if (@today=0)(select @case='zero')
    if (@today=1)(select @case='one')
    if (@today>1)(select @case='other')
    select cfv.value, cfv.companyId
    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 ((@case='other') 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 ((@case ='zero') AND(cfv.value='0')) THEN 1
        WHEN ((@case ='one') AND(cfv.value='1' or cfv.value='0,1')) THEN 1
        ELSE 0
    END = 1
    

    非常感谢您的帮助,您的建议对我帮助很大;)

    【讨论】:

      猜你喜欢
      • 2013-12-31
      • 2015-01-30
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 2015-04-08
      • 1970-01-01
      相关资源
      最近更新 更多