1

就在那时,我还有一个。这与我之前使用的过程相同。结果不是我需要的,所以回到绘图板上。系统是一样的:

SQL Server 2005 || Excel 2007 || SQL 管理工作室 2008R2

我在比较两个日期时遇到问题。SSMS 抛出的错误毫无意义。这是代码:

declare @calendar_start char(8)
declare @years int

set @calendar_start = '20130101'
set @years = 1

----------------------------------------------------------------------------
-- standard declaration stuff.  -
----------------------------------------------------------------------------

-- for ease of entry, I convert the start timeto a real time ---------------
----------------------------------------------------------------------------
declare @startdate datetime
set     @startdate = CONVERT (datetime, @calendar_start, 112)

-- to calculate the end of the forecast, I use the start date and add the --
-- provided number of year -------------------------------------------------
----------------------------------------------------------------------------
declare @enddate datetime
set     @enddate = dateadd(year,+@years,@startdate)
----------------------------------------------------------------------------

-- I need a variable to advance the plotting month. the plotting month is --
-- how I am going to spread out the project all year from a single date ----
----------------------------------------------------------------------------
declare @counter int
set     @counter = 0
----------------------------------------------------------------------------

----------------------------------------------------------------------------
-- this table will be used to have all the calendar dates by year-month ----
----------------------------------------------------------------------------
create table #calendar (calenderid char(6))

insert into #calendar
    select 
        distinct left(calendarid,6) [yearmonth]
    from 
        [cmdb_core].[dbo].[Calendar] 
    where 
        datevalue between @startdate and @enddate
----------------------------------------------------------------------------

----------------------------------------------------------------------------
-- rather than hitting the database any number of times, I load the whole --
-- of the computed estimates table into memory. it is faster that way.  ----
----------------------------------------------------------------------------
create table #baseline (
    [adjusted_ExpectedActionDt] datetime
    ,[key] text
    ,projectid text
    ,projectnm text
    ,ParentChaseProjectNo text
    ,VersionTag text
    ,itemid text
    ,Qty int
    ,ItemNotes text
    ,CashflowType text
    ,frequency text
    ,UnitPrice float
    ,[cost] float
)

insert into #baseline (
    [adjusted_ExpectedActionDt]
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,[cost]
)
select  
    case
        when (ExpectedActionDt is not null)
            then ExpectedActionDt
        when (IntegratedReleasePlanDt is not null)
            then IntegratedReleasePlanDt
        else
            DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
    end [adjusted_ExpectedActionDt]
    ,cast(ModelEstimateId as nvarchar(max))+cast(BucketId as nvarchar(max))+cast(ItemNo as nvarchar(max)) [key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo   
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,null [cost]
from 
    estimate.ComputedEstimates
where
        [status] <> 'Hold'
    and CostCategory <> 'Assembly'
    and includeinforecast = 'Y'
    and cashflowtype <> 'Notional'
    and Qty <> 0
    and case
            when (ExpectedActionDt is not null)
                then ExpectedActionDt
            when (IntegratedReleasePlanDt is not null)
                then IntegratedReleasePlanDt
            else
                DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
        end between @startdate and @enddate
--------------------------------------------------------------------------

--------------------------------------------------------------------------
-- we need a place to contain the results of the interation through the --
-- baseline temp table. the results table will be that. ------------------
--------------------------------------------------------------------------
create table #results (
    [adjusted_ExpectedActionDt] datetime
    ,[plot_date] datetime
    ,[key] text
    ,projectid text
    ,projectnm text
    ,ParentChaseProjectNo text
    ,VersionTag text
    ,itemid text
    ,Qty int
    ,ItemNotes text
    ,CashflowType text
    ,frequency text
    ,UnitPrice float
    ,[cost] float
)

-- this loop is how we will build the results. it is governed by the -----
-- date. as I iterate through the loop, I incriment the plot date so -----
-- that I can show a project and it's costs over the range of dates ------
-- rather than only the month it goes into production --------------------
--------------------------------------------------------------------------
WHILE (@startdate <= @enddate)
BEGIN
insert into #results (
    [adjusted_ExpectedActionDt]
    ,[plot_date]
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,[cost]
)
select 
    [adjusted_ExpectedActionDt]
    ,dateadd(month,+@counter,[adjusted_ExpectedActionDt])
    ,[key]
    ,projectid
    ,projectnm
    ,ParentChaseProjectNo
    ,VersionTag
    ,itemid
    ,Qty
    ,ItemNotes
    ,CashflowType
    ,frequency
    ,UnitPrice
    ,case
        when frequency = 'OneTime' 
            then 
--=====================================================================--
--===================== this is where the problem is ==================--
--=====================================================================--           
                case
                    when dateadd(mm, datediff(mm,0, [adjusted_ExpectedActionDt]), 0) = 
                         dateadd(mm, datediff(mm,0, dateadd(month,+@counter,[adjusted_ExpectedActionDt])), 0)
                        then [Qty]
                    else
                        0
                end
--=====================================================================--
--=====================================================================--
        else
            cast(round((UnitPrice*Qty)/12,0) as int)
        end [cost]
 from #baseline

set @counter = @counter+1
set @startdate = dateadd(month,+1,@startdate)
END
--------------------------------------------------------------------------

--------------------------------------------------------------------------
-- now we have to return the results but it is not enough to just dump ---
-- the table, I have to add a date that covers all month regardless of ---
-- that month's presence in the results table. I use the calendar temp, --
-- which has those dates as a basis of the outer join --------------------
--------------------------------------------------------------------------

select  
    c.calenderid
    ,r.[adjusted_ExpectedActionDt]
    ,r.[plot_date]
    ,r.[key]
    ,r.projectid
    ,r.projectnm
    ,r.ParentChaseProjectNo
    ,r.VersionTag
    ,r.itemid
    ,r.Qty
    ,r.ItemNotes
    ,r.CashflowType
    ,r.frequency
    ,r.UnitPrice
    ,r.[cost] 
from 
    #calendar c
    left outer join
    #results r
    on c.calenderid = cast(year(r.[adjusted_ExpectedActionDt])as char(4))+RIGHT('0'+ CONVERT(VARCHAR,month(r.[adjusted_ExpectedActionDt])),2)
--------------------------------------------------------------------------
GO

问题是:

--=====================================================================--
--===================== this is where the problem is ==================--
--=====================================================================--           
                case
                    when dateadd(mm, datediff(mm,0, [adjusted_ExpectedActionDt]), 0) = 
                         dateadd(mm, datediff(mm,0, dateadd(month,+@counter,[adjusted_ExpectedActionDt])), 0)
                        then [Qty]
                    else
                        0
                end
--=====================================================================--
--=====================================================================--

当我尝试运行此代码时,出现以下错误:

Msg 402, Level 16, State 1, Line 149
The data types text and varchar are incompatible in the equal to operator.

这是最令人烦恼的,因为比较是日期匹配而不是文本。这是我尝试过的: 1. 大量的互联网搜索 2. 将 case 语句更改为 if 语句,但无法获得正确的语法。3. 将日期更改为 datepart 功能仅拉年份。我们知道应该返回一个 int 4. 将比较更改为“1=1”,这显然是数字并且应该始终为真 5. 尝试转换为连接文本 (yyyymm) 6. 与我们的一位 SQL 开发人员交谈(我是不是按标题,但希望在这个项目结束时出现:))

真正奇怪的是这个通用代码有效

select 
    dateadd(mm, datediff(mm,0, getdate()), 0)
    ,dateadd(mm, datediff(mm,0, getdate()+60), 0)
    ,case
        when dateadd(mm, datediff(mm,0, getdate()), 0) = 
             dateadd(mm, datediff(mm,0, getdate()+60), 0)
            then 'matches'
        else
            'different'
    end

最后一点信息是,如果我评论有问题的代码只留下 [Qty] 字段,它运行良好。

帮帮我欧比-任何人,你是我唯一的希望。先感谢您。

4

1 回答 1

1

我认为问题不在于您的 CASE 声明的那一部分,我认为是:

when frequency = 'OneTime'

因为频率列是数据类型文本。

你可以试试:

  when cast(frequency as varchar(20)) = 'OneTime'

或者其他的东西。

于 2013-03-18T19:05:08.737 回答