【问题标题】:Perform a Series of Calculations on a Multiple CTE Table对多个 CTE 表执行一系列计算
【发布时间】:2019-01-22 22:40:11
【问题描述】:

似乎无法弄清楚对我的查询执行一系列函数的公式。我需要根据 STAT 代码减去 DIF 列中的数字。在每种情况下,我都需要执行相同的一系列功能。 STAT I0099 MINUS E0002,这个结果将永远是分母。在此之后,我需要将表格中的其他每一行都除以这个结果。

第 1 次 (2811-98)、第 2 次 E0013 (52/(2811-98)) 第 3 次 E0019 (405/(2811-98)) 第 4 次 E0004 (2256/(2811-98) 结束。

我已经尝试添加汇总和其他一些东西,我在这里看到了,但没有一个成功。

WITH i_stat_cte
AS
(
SELECT ROW_NUMBER() OVER(partition by STAT Order by UDATE ) as 
Rn,JCDS_SOGR.OBJNR, JCDS_SOGR.STAT,JCDS_SOGR.UDATE,JCDS_SOGR.CHGNR,JCDS_SOGR.CDTCODE,JCDS_SOGR.CHIND,JCDS_SOGR.INACT,JCDS_SOGR.TCODE,TJ02T.TXT30, EQUI.BAUJJ as "Year", T370K_T.EARTX as Model,
LAG(UDATE) OVER(partition by STAT Order by UDATE ) As PrevUDate,
COUNT(*) OVER(partition by STAT) As [Count]
from JCDS_SOGR
Join TJ02T on JCDS_SOGR.STAT = TJ02T.ISTAT
Join EQUI on JCDS_SOGR.OBJNR = EQUI.OBJNR
Join T370K_T on equi.EQART = T370K_T.EQART
where jcds_sogr.OBJNR = 'IE000000000010003137'
and TJ02T.SPRAS = 'E'
)
,
e_stat_cte
AS
(
SELECT ROW_NUMBER() OVER(partition by STAT Order by UDATE ) as Rn, JCDS_SOGR.OBJNR, JCDS_SOGR.STAT,JCDS_SOGR.UDATE,JCDS_SOGR.CHGNR,JCDS_SOGR.CDTCODE,JCDS_SOGR.CHIND,JCDS_SOGR.INACT,JCDS_SOGR.TCODE,TJ30T.TXT30, EQUI.BAUJJ as "Year", T370K_T.EARTX as Model,
LAG(UDATE) OVER(partition by STAT Order by UDATE ) As PrevUDate,
COUNT(*) OVER(partition by STAT) As [Count], TJ30T.MANDT as Client
from JCDS_SOGR
Join TJ30T on JCDS_SOGR.STAT = TJ30T.ESTAT
Join EQUI on JCDS_SOGR.OBJNR = EQUI.OBJNR
Join T370K_T on equi.EQART = T370K_T.EQART
where jcds_sogr.OBJNR = 'IE000000000010003137'
and TJ30T.SPRAS = 'E'AND TJ30T.MANDT='400'
AND TJ30T.STSMA = 'VEHICLE' AND T370K_T.MANDT = '400')

SELECT Max(rn) As [Count],
OBJNR,Year, Model, STAT,TXT30,
SUM(CASE WHEN rn%2=0 THEN DATEDIFF(d,PrevUDate,UDATE) 
    WHEN rn=[Count] THEN  DATEDIFF(d,UDATE,getDate())   
ELSE 0 END) as DIF
from i_stat_cte
Group BY OBJNR, STAT,TXT30, Year, Model

UNION

SELECT Max(rn) As [Count],
OBJNR,Year, Model, STAT,TXT30,
SUM(CASE WHEN rn%2=0 THEN DATEDIFF(d,PrevUDate,UDATE) 
    WHEN rn=[Count] THEN  DATEDIFF(d,UDATE,getDate())   
ELSE 0 END) as DIF
from e_stat_cte
Group BY OBJNR, STAT,TXT30, Year, Model

预期结果

Count   OBJNR                  Year Model   STAT    TXT30   DIF   Avail | Calculations
1   IE000000000010003137    2011    Orion  I0099    Avail  2810 
2   IE000000000010003137    2011    Orion  E0002    Await  98   
4   IE000000000010003137    2011    Orion  E0013    Non Op 52     .0191740  = (52/(2810-98))
4   IE000000000010003137    2011    Orion  E0019    OperBk 405    .1493363  = (405/(2810-98))
7   IE000000000010003137    2011    Orion  E0004    Oper   2255   .8314897  = (2255/(2810-98))

【问题讨论】:

  • 您是否考虑过使用临时表,以便在使用它们之前查看每个表的结果? CTE 的执行速度非常慢,主要是因为人们在编写它们时不考虑任何索引。
  • 不完全确定我将如何进行修改,但我会尝试查找它。谢谢你的建议。

标签: sql ssms ssms-2017


【解决方案1】:

--下面的代码是您的代码从 CTE 到临时表的转换。 --希望您可以对其进行更好的诊断。只需评估您在上次查询中生成的每个数据。我认为UNION有点草率。你确定它真的是 UNION 而不是 UNION ALL?

DROP TABLE IF EXISTS #i_stat_cte

SELECT ROW_NUMBER() OVER(partition by STAT Order by UDATE ) as 
Rn,JCDS_SOGR.OBJNR, JCDS_SOGR.STAT,JCDS_SOGR.UDATE,JCDS_SOGR.CHGNR,JCDS_SOGR.CDTCODE,JCDS_SOGR.CHIND,JCDS_SOGR.INACT,JCDS_SOGR.TCODE,TJ02T.TXT30, EQUI.BAUJJ as "Year", T370K_T.EARTX as Model,
LAG(UDATE) OVER(partition by STAT Order by UDATE ) As PrevUDate,
COUNT(*) OVER(partition by STAT) As [Count]
INTO #i_stat_cte
from JCDS_SOGR
Join TJ02T on JCDS_SOGR.STAT = TJ02T.ISTAT
Join EQUI on JCDS_SOGR.OBJNR = EQUI.OBJNR
Join T370K_T on equi.EQART = T370K_T.EQART
where jcds_sogr.OBJNR = 'IE000000000010003137'
and TJ02T.SPRAS = 'E'

DROP TABLE IF EXISTS #e_stat_cte

SELECT ROW_NUMBER() OVER(partition by STAT Order by UDATE ) as Rn, JCDS_SOGR.OBJNR, JCDS_SOGR.STAT,JCDS_SOGR.UDATE,JCDS_SOGR.CHGNR,JCDS_SOGR.CDTCODE,JCDS_SOGR.CHIND,JCDS_SOGR.INACT,JCDS_SOGR.TCODE,TJ30T.TXT30, EQUI.BAUJJ as "Year", T370K_T.EARTX as Model,
LAG(UDATE) OVER(partition by STAT Order by UDATE ) As PrevUDate,
COUNT(*) OVER(partition by STAT) As [Count], TJ30T.MANDT as Client
INTO #e_stat_cte
from JCDS_SOGR
Join TJ30T on JCDS_SOGR.STAT = TJ30T.ESTAT
Join EQUI on JCDS_SOGR.OBJNR = EQUI.OBJNR
Join T370K_T on equi.EQART = T370K_T.EQART
where jcds_sogr.OBJNR = 'IE000000000010003137'
and TJ30T.SPRAS = 'E'AND TJ30T.MANDT='400'
AND TJ30T.STSMA = 'VEHICLE' AND T370K_T.MANDT = '400'

 -- VERIFY YOU GET WHAT YOU EXPECT
select * from #i_stat_cte    

 -- VERIFY YOU GET WHAT YOU EXPECT
select * from #e_stat_cte    

 -- VERIFY YOU GET WHAT YOU EXPECT
SELECT Max(rn) As [Count],
OBJNR,Year, Model, STAT,TXT30,
SUM(CASE WHEN rn%2=0 THEN DATEDIFF(d,PrevUDate,UDATE) 
    WHEN rn=[Count] THEN  DATEDIFF(d,UDATE,getDate())   
ELSE 0 END) as DIF
from #i_stat_cte
Group BY OBJNR, STAT,TXT30, Year, Model

--UNION    

 -- VERIFY YOU GET WHAT YOU EXPECT
SELECT Max(rn) As [Count],
OBJNR,Year, Model, STAT,TXT30,
SUM(CASE WHEN rn%2=0 THEN DATEDIFF(d,PrevUDate,UDATE) 
    WHEN rn=[Count] THEN  DATEDIFF(d,UDATE,getDate())   
ELSE 0 END) as DIF
from #e_stat_cte
Group BY OBJNR, STAT,TXT30, Year, Model

【讨论】:

  • 非常感谢 Earl,我现在正在尝试,但不断收到一条消息:“Msg 2714, Level 16, State 6, Line 2 数据库中已经有一个名为 '#i_stat_cte' 的对象。”关于 UNION 与 UNION ALL,表中没有重复项,这就是我们选择 Union 的原因。
  • 非常感谢 Earl,我发现了错误信息。该脚本运行良好。
  • 现在我将对此进行一些计算,希望我能更接近添加计算字段。
  • Earl 关于 OBJNR ='IE000000000010031347' 我可以为这个字段创建一系列这样的字段吗?
  • 嗨。也许你的意思是 jcds_sogr.OBJNR IN ('IE000000000010003137','IE000000000010003138','IE000000000010003139')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多