【问题标题】:How to calculate table values dynamically and find Min and Max target from parameter in SQL Server如何动态计算表值并从 SQL Server 中的参数中找到 Min 和 Max 目标
【发布时间】:2019-05-28 03:16:37
【问题描述】:

我想动态计算表格值并从参数中找到最小值和最大值目标

我有以下带有数据的目标表:

Name        Quarter Method  MethodID    GivenTarget Percentage 
Json Ray    1       AB      1           153000      0.2 
Json Ray    1       BC      2           208000      0.5 
Json Ray    1       CD      3           252000      0.8 
Json Ray    1       DE      4           450000      0.2 
Json Ray    2       AB      1           223000      1.4 
Json Ray    2       BC      2           308000      1.8 
Json Ray    2       CD      3           352000      1.2 
Json Ray    2       DE      4           550000      1.5 
Json Ray    3       AB      1           323000      2.8 
Json Ray    3       BC      2           408000      2.3 
Json Ray    3       CD      3           552000      2.4 
Json Ray    3       DE      4           650000      2.9 
Json Ray    4       AB      1           423000      2.2 
Json Ray    4       BC      2           508000      3.3 
Json Ray    4       CD      3           652000      3.5 
Json Ray    4       DE      4           750000      3.9 

我正在为特定季度(1、2、3、4)传递一个参数AchievedTarget

如果季度 = 1 和成就目标 = 250000 我想要成就目标介于两者之间的记录

输出应该是这样的:

如果季度 = 1 和成就目标 = 400000 我想要成就目标介于两者之间的记录

输出应该是这样的:

如果季度 = 2 和成就目标 = 400000,我想对目标表中的 GivenTarget 列求和,其中季度 = 1,方法 = 'AB',Method_ID = 1 使用 Quarter= 2 Method = 'AB' Method_ID = 1 以此类推,以添加每个相应的方法和 Method_ID 与季度,并且需要从当前季度中选择百分比值,即在这种情况下为第 2 季度,具有相应的 Method 和 Method_ID

第 2 季度的预期新目标表应如下所示:

现在根据上表我想计算之前计算的 Min_Target 和 Max_Target

Quarter= 2 和 AchievedTarget= 500000 的预期输出应该是:

以下是我正在尝试的代码,它只给了我 Quarter = 1 的输出

--DECLARE Input Parameters
DECLARE @AchievedTarget Money =200000                          
DECLARE @Name varchar(30)='Json Ray' , @Quarter int =1, @Mothod varchar(10)='AB'    

--DECLARE Ouput variable
DECLARE @Min_Target Money, @Max_Target Money, @Min_Percenatge float ,@Max_Percenatge float                         

--Finding Min_Target    
SET @Min_Target=(SELECT TOP 1 [GivenTarget] as Min_Target
FROM [Target]
WHERE  [Name] = @Name
AND Quarter = @Quarter 
AND Mothod =@Mothod 
and [GivenTarget] < @AchievedTarget
order by [GivenTarget] desc)
IF @Min_Target IS Null 
SET @Min_Target=(@AchievedTarget)

--Finding Max_Target
SET @Min_Target=(SELECT TOP 1 [GivenTarget] as Min_Target
FROM [Target ]
WHERE  [Name] = @Name
AND Quarter = @Quarter 
AND Mothod =@Mothod 
and [GivenTarget] < @AchievedTarget
order by [GivenTarget] ASC)
IF @Max_Target IS Null 
SET @Max_Target=(@AchievedTarget)

--Finding @Min_Percenatge
SET @Min_Percenatge=(SELECT TOP 1 [Percenatge] AS Min_Percenatge
from [Target ]  
WHERE  [Name] = @Name
AND Quarter = @Quarter 
AND Mothod =@Mothod  
AND [GivenTarget] in (@Min_Target,@Max_Target))

--Finding @Max_Percenatge
SET @Max_Percenatge=(SELECT TOP 1 [Percenatge] AS Max_Percenatge
from [Target ]  
WHERE  [Name] = @Name 
AND Quarter = @Quarter 
AND Mothod =@Mothod 
AND [GivenTarget] in (@Min_Target,@Max_Target) 
ORDER BY [Percenatge] DESC)

--Display Ouput
SELECT @Name, @Quarter,@Mothod ,@Min_Target, @Max_Target, @Min_Percenatge,@Max_Percenatge

我无法动态计算表值并从参数季度中找到最小和最大目标。

【问题讨论】:

  • 如果我们不必从图像中输入您的源数据,这个问题会更容易解决。请以文本格式而不是图像粘贴数据。
  • 嗨 TomC,以下是文本中的源表数据 Name Quarter Method MethodID GivenTarget Percentage Json Ray 1 AB 1 153000 0.2 Json Ray 1 BC 2 208000 0.5 Json Ray 1 CD 3 252000 0.8 Json Ray 1 DE 4 450000 0.2 Json Ray 2 AB 1 223000 1.4 Json Ray 2 BC 2 308000 1.8 Json Ray 2 CD 3 352000 1.2 Json Ray 2 DE 4 550000 1.5 Json Ray 3 AB 1 323000 2.8 Json Ray 3 BC 2 408000 2 552000 2.4 Json Ray 3 DE 4 650000 2.9 Json Ray 4 AB 1 423000 2.2 Json Ray 4 BC 2 508000 3.3 Json Ray 4 CD 3 652000 3.5 Json Ray 4 DE 4 750000 3.9
  • CREATE TABLE [dbo].[Target]( [Name] [nvarchar](255) NULL, [Quarter] [float] NULL, [Method] [nvarchar](255) NULL, [MethodID ] [float] NULL, [GivenTarget] [float] NULL, [Percentage] [float] NULL ) ON [PRIMARY] 谢谢
  • 感谢@sparta_saggy,我已经编辑了问题以显示您的数据应该去哪里。您可以随时编辑问题以添加额外信息。
  • 根据您的测试数据,每个方法每个季度只有一个条目。所以你只会看一行。

标签: sql sql-server database tsql


【解决方案1】:

我已经整理了一组示例数据和查询来执行此操作。我删除了对 Mothod 的引用,因为每个 Mothod 每季度只有 1 行。如果您有比示例更多的行,您可以将该列重新添加到我的解决方案中。

先建表并测试数据

declare @comm table(Name varchar(20), Qtr int, Mothod varchar(2), Method_ID int, GivenTarget int, Pct decimal(5,2))
insert @comm values 
('Json Ray',1,'AB',1,153000,0.2 )
,('Json Ray',1,'BC',2,208000,0.5 )
,('Json Ray',1,'CD',3,252000,0.8 )
,('Json Ray',1,'DE',4,450000,0.2 )
,('Json Ray',2,'AB',1,223000,1.4 )
,('Json Ray',2,'BC',2,308000,1.8 )
,('Json Ray',2,'CD',3,352000,1.2 )
,('Json Ray',2,'DE',4,550000,1.5 )
,('Json Ray',3,'AB',1,323000,2.8 )
,('Json Ray',3,'BC',2,408000,2.3 )
,('Json Ray',3,'CD',3,552000,2.4 )
,('Json Ray',3,'DE',4,650000,2.9 )
,('Json Ray',4,'AB',1,423000,2.2 )
,('Json Ray',4,'BC',2,508000,3.3 )
,('Json Ray',4,'CD',3,652000,3.5 )
,('Json Ray',4,'DE',4,750000,3.9 )

添加一个顶行,以防万一达到高于您的最高目标的人

insert @comm
select Name, qtr, null, null, 999999, max(pct) from @comm group by Name, qtr

设置你的条件。我已经取出了 Mothod,因为每个 Qtr 每个 Mothos 只有一行

DECLARE @AchievedTarget Money                          
DECLARE @Name varchar(30), @Quarter int 
select @AchievedTarget=500000,  @Name='Json Ray' , @Quarter=2

使用 CTE 获取每个 qtr 的累积总数,并使用第二个 CTE 来展平每一行,使其也具有前一行的值。我已经使用 row_number 来确保我正确地对您的行进行排序,即使在您的示例日期 mothod_id 似乎也具有相同的数据。

然后,最终查询只是从 CTE 中找到正确的行。

;with c as (
select Name, upto as qtr, Mothod, Method_ID, 
    sum(GivenTarget) as GivenTarget, 
    max(case when c.qtr=q.upto then c.pct else 0 end) as Pct,
    row_number() over (partition by Name, upto order by sum(GivenTarget)) as rn 
from @comm c
join (select distinct qtr as upto from @comm) q on c.qtr<=upto
group by Name, upto, Mothod, Method_ID
)
, c2 as (
select c.Name, c.Qtr, c.GivenTarget as MaxTarget, c.Pct as MaxPct, 
    isnull(c2.GivenTarget,0) as MinTarget, isnull(c2.Pct,0) as MinPct 
from c
left join c c2 on c2.name=c.name and c2.qtr=c.qtr and c2.rn=c.rn-1
where c.name=@name and c.qtr=@Quarter 
)
select Name, Qtr, MinTarget, MaxTarget, MinPct, MaxPct 
from c2
where @AchievedTarget>MinTarget and @AchievedTarget<=MaxTarget

结果,使用@qtr=2 和@achieved=500000:

Name       Qtr  MinTarget   MaxTarget   MinPct  MaxPct
Json Ray    2   376000      516000      1.40    1.80

【讨论】:

    【解决方案2】:

    您应该能够只在计算最小值和最大值的子查询上使用 WHERE 子句。像这样的:

    declare @quarter int = 2;
    declare @achieved_target money = 300000.00;
    
    SELECT *
    FROM (select name, min(achieved_target) as min_target, max(achieved_target) as max_target FROM table WHERE quarter = @quarter GROUP BY name) as t1
    WHERE @achieved_target BETWEEN min_target and max_target;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 2019-12-24
      相关资源
      最近更新 更多