Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在执行计算时迭代SQL中的值?_Sql_Sql Server_Recursion_Common Table Expression - Fatal编程技术网

如何在执行计算时迭代SQL中的值?

如何在执行计算时迭代SQL中的值?,sql,sql-server,recursion,common-table-expression,Sql,Sql Server,Recursion,Common Table Expression,我这里有一个比较复杂的场景: 我有一个查询,它告诉我某个计划对表中指定的卷的影响。如果卷为1000,更改为-500,则新卷为500。同样的逻辑也适用于利率。以下是更新新数量、新费率、新需求工时和新需求FTE的查询 select x.mdc_code, x.cal_month, x.cal_year, x.activity, y.scenario_id, y.initiative_id, x.volume, x.rate, y.metric_to_be_applied, y.change,

我这里有一个比较复杂的场景:

我有一个查询,它告诉我某个计划对表中指定的卷的影响。如果卷为1000,更改为-500,则新卷为500。同样的逻辑也适用于利率。以下是更新新数量、新费率、新需求工时和新需求FTE的查询

select 
x.mdc_code, x.cal_month, x.cal_year, x.activity,  y.scenario_id, 
 y.initiative_id, x.volume, x.rate, y.metric_to_be_applied, y.change,

CASE WHEN y.metric_to_be_applied = 'Volume'
THEN x.volume + y.change end as New_Volume_VolumeChange ,
CASE WHEN y.metric_to_be_applied = 'Volume'
THEN x.rate end as New_Rate_VolumeChange,
CASE WHEN y.metric_to_be_applied = 'Volume'
THEN (x.volume + y.change)/x.rate end as New_DemandHours_VolumeChange,
CASE WHEN y.metric_to_be_applied = 'Volume'
THEN ((x.volume + y.change)/x.rate)/176 end as New_DemandFTE_VolumeChange,
CASE WHEN y.metric_to_be_applied = 'Rate'
THEN x.volume end as New_Volume_RateChange ,
CASE WHEN y.metric_to_be_applied = 'Rate'
THEN x.rate + y.change end as New_Rate_RateChange,
CASE WHEN y.metric_to_be_applied = 'Rate'
THEN (x.volume)/(x.rate + y.change) end as New_DemandHours_RateChange,
CASE WHEN y.metric_to_be_applied = 'Rate'
THEN ((x.volume)/(x.rate+ y.change))/176 end as New_DemandFTE_RateChange
from
(SELECT  [id] as activity_id
  ,[mdc_code]
  ,[function_name]
  ,[cal_month]
  ,[cal_year]
  ,[model_type]
  ,[activity]
  ,[activity_type]
  ,[product_category]
  ,[project_category]
  ,[segment]
  ,[volume]
  ,[demand_fte]
  ,[demand_hours]
  ,[rate]
  ,[sub_division_name]
  ,[division_name]
  ,[myp_year]
  ,[client_count]
  ,[calls]
  ,[loguser]
  ,[logdate]
  ,[IsProd]
  ,[version_id]
FROM [myp_activity]
)x

join

(
SELECT [id]
  ,[scenario_id]
  ,[initiative_id]
  ,[initiative_name]
  ,[comments]
  ,[recommended_by]
  ,[mdc_code]
  ,[function_name]
  ,[cal_month]
  ,[cal_year]
  ,[model_type]
  ,[activity]
  ,[metric_to_be_applied]
  ,[change_type]
  ,[change]
  ,[sub_division_name]
  ,[division_name]
  ,[myp_year]
  ,[loguser]
  ,[logdate]
  ,[IsProd]
  ,[version_id]
  ,[initiative_type]
  FROM [myp_initiatives] where initiative_id=10001
 ) y
on x.mdc_code = y.mdc_code
and x.cal_month = y.cal_month
and x.cal_year = y.cal_year
and x.activity = y.activity
我对此查询有以下输出:

还有4列未在图片中列出(新数量、新费率、新需求时费率、新需求时费率)

我需要对这些数据应用倡议10002。计划10002的详细信息见已用于加入的计划表。现在输出已经应用了主动10001。 例如: 如果计划10001的某一行中列出的卷为500,而计划2的更改为-300,则输出应该有200作为该特定行中列出的卷列。 此外,方案id应从10001更改为10002,因为方案10002是最后应用的方案

同样,如果我们列出了将应用于方案10002的方案10003,那么输出应将10003列为方案

因此,应将计划10002、10003等应用于从上述查询生成的我的数据

在所有这些情况下,两个表(主动性和活动)的联接条件都将与查询中列出的相同

我如何做到这一点


我试过CTE,但做不到。我不知道如何对其执行计算(CASE-WHEN语句)。

虽然您可能会或可能不会得到包含代码修改版本的答案,但您可能希望查看下面的简化查询,以了解解决“运行值”问题的一种方法

DECLARE @Initiative TABLE (IntiativeID INT, AddToValue INT, Code NVARCHAR(10))
DECLARE @Data TABLE(DataID INT, Value INT, Code NVARCHAR(10))

INSERT @Data VALUES(1,10,'A'),(2,10,'B'),(3,10,'A')
INSERT @Initiative VALUES(1,5,'A'),(2,5,'A'),(4,5,'B'),(800,5,'C'),(24,5,'D')


SELECT 
    DataId,
    StartValue = Value,
    LastIntiativeID = MAX(IntiativeID),
    EndValue = Value + SUM(AddToValue)
FROM 
    @Data D 
    LEFT JOIN  @Initiative I ON D.Code = I.Code
GROUP BY 
    DataID,Value
ORDER BY
    DataID
编辑

这几乎是对我以前的答案的完全重写

不过,正如前面提到的,我会丢失所有的括号…它们只会让你的代码更不可读。实际上,只有当列名与SQL中的保留字冲突时,才需要它们

接下来,您不必从
select
到alias中
select
,也不必担心在中间结果中获得额外数据。在进行某种聚合或计算时,实际上应该只从
select
中选择
。一个很好的例子是你的
y
…在这里你可以计算计算的基本因子…然后完全摆脱
案例
s…如下所示:

select 
  x.mdc_code, x.cal_month, x.cal_year, x.activity,  y.scenario_id, 
  y.initiative_id, x.volume, x.rate, y.metric_to_be_applied, y.change,

  x.volume + applied_volume as New_Volume_VolumeChange ,
  x.rate * applied_volume as New_Rate_VolumeChange,
  (x.volume + applied_volume)/x.rate as New_DemandHours_VolumeChange,
  ((x.volume + applied_volume)/x.rate)/176 as New_DemandFTE_VolumeChange,
  x.volume + applied_rate as New_Volume_RateChange ,
  x.rate * applied_rate as New_Rate_RateChange,
  (x.volume)/(x.rate + applied_rate) as New_DemandHours_RateChange,
  ((x.volume)/(x.rate+ applied_rate))/176 as New_DemandFTE_RateChange
from
  myp_activity x
  inner join
  ( select 
      iif( metric_to_be_applied = 'Volume', change, null ) as applied_volume,
      iif( metric_to_be_applied = 'Rate', change, null ) as applied_rate,
      mdc_code, cal_month, cal_year, activity, scenario_id, initiative_id, metric_to_be_applied, change
    from 
      myp_initiatives
  ) as y
on 
    x.mdc_code = y.mdc_code
    and x.cal_month = y.cal_month
    and x.cal_year = y.cal_year
    and x.activity = y.activity
where 
  y.initiative_id=10001
从概念上讲,这是完全合适的,然而,您的要求意味着一个简单的CTE不能应用于问题……据我所知。这是因为我没有办法重复我可以制定的计划。相反,让我提供一个函数,它将以您需要的方式(我认为)聚合更改

但是,请注意一些重要的事情。我不知道列的数据类型,所以这个函数将所有内容声明为
int
,我确信这是不对的。您必须编辑数据类型以匹配您真正拥有的数据类型

这里发生的事情是,函数首先将第一组值写入表
@t
,然后将结果应用到每个先前的倡议并将其写入
@t
,插入更新的值。最后,它返回表

定义此函数后,您可以说:

select
  * --> note: would be better to list columns...but I'm being lazy for clarity
from
  AppliedInitiatives()

如果有人能把它改写成cte,对我来说也是一次学习的经历

我能理解你的一系列计划吗?也就是说,在10001和10002的结果中加入10001和10002,然后在10001和10002的结果中加入10003?是否有固定数量的计划…或者有很多计划?以及…是否所有的中间结果都要显示?还是我们只对最终的应用计划感兴趣?这是一个很好的开始,我不需要显示中间结果。是的,10002应用于10001,给我一个新的数据集,10003将应用于该数据集。我得到以下错误:“Msg 240,16级,状态1,行1类型在递归查询“base”的“mdc_代码”列中的锚和递归部分之间不匹配”。“知道我哪里出错了吗?是的……我在第二部分输入了错误。”(递归部分)…应该是x.mdc\u代码、x.cal\u月、x.cal\u年、x.activity选择列表…已修复it@AsheshDas我更新了代码…让我知道你是如何处理它的。嗨,克莱,当我为initiative_id=10002执行这个CTE时,行数从336增加到2688。知道为什么会发生这种情况吗?还有当initiative 10002应用时的新卷应该是=(initiative 10001的新卷)+(change in 10002),输出中显示的initiative_id应该是10002。我如何合并它?在更改数据类型并执行函数后,我得到了一个“Divide by zero error Incometed.”错误。我知道如何避免这个错误吗?
select
  * --> note: would be better to list columns...but I'm being lazy for clarity
from
  AppliedInitiatives()