【问题标题】:Using Multiple CTEs使用多个 CTE
【发布时间】:2014-10-09 11:54:49
【问题描述】:

当我使用 Group BY 获取月份数据时,我得到每个 CTE 的重复结果。这是问题出在哪里的查询的一部分。在 CTE 上创建的列的基础上进行计算。 请帮忙...

DECLARE @StartDate datetime
SET @StartDate='12/01/2012'
WHILE @StartDate<'12/02/2012' --Set GETDATE()
BEGIN
WITH CTE3 (Parameter,Month3,Count3,Count2,Count1,DateRange,OrgID)    
 AS    
  (    
  SELECT CAST(Col1 AS VARCHAR(50)) Parameter
  ,SUM(CASE WHEN DateRange=CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate),0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))
  THEN Col2 else 0 END) Month3
  ,(SELECT COUNT(Col1) FROM [Table_Name] 
  WHERE Col1='INS Charges'   
  AND DateRange = CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate),0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))) Count3
  ,(SELECT COUNT(Col1) FROM [Table_Name]
  WHERE DateRange = CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate)-1,0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))) Count2  
  ,(SELECT COUNT(Col1) FROM [Table_Name]   
  WHERE DateRange = CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate)-2,0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))) Count1  
  ,DateRange
  ,OrgID
  FROM [Table_Name]
  WHERE DateRange=CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate),0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))
  GROUP BY Col1,OrgID,DateRange
  )
  ,CTE2 (Parameter,Month2,DateRange,OrgID)
  AS
  (
    SELECT CAST(Col1 AS VARCHAR(50)) Parameter
    ,SUM(Col2) Month2
    ,DateRange
    ,OrgID
    from [Table_Name]
    WHERE DateRange= CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate)-1,0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))
    GROUP BY Col1,OrgID,DateRange
  )
  ,CTE1 (Parameter,Month1,DateRange,OrgID)
  AS
  (
    SELECT CAST(Col1 AS VARCHAR(50)) Parameter
    ,SUM(Col2) Month1
    ,DateRange
    ,OrgID
    from [Table_Name]
    WHERE DateRange= CAST(LEFT(DATENAME(MONTH,DATEADD(MONTH,DATEDIFF(M,0,@StartDate)-2,0)),3) + '-' + DATENAME(YYYY,@StartDate) AS VARCHAR(50))
    GROUP BY Col1,DateRange,OrgID
  )
  SELECT CTE3.Parameter    
  ,CTE1.Month1
  ,CTE2.Month2    
  ,CTE3.Month3
  ,CTE1.Month1+CTE2.Month2+CTE3.Month3 YTD
  ,(CTE1.Month1+CTE2.Month2+CTE3.Month3)/3 [3 Month Avg]
  ,Cte3.OrgID
  ,Cte3.DateRange
  FROM CTE3
  JOIN CTE1 ON CTE1.Parameter=CTE3.Parameter
  JOIN CTE2 ON CTE2.Parameter=CTE3.Parameter
  SET @StartDate=(SELECT DATEADD(M,1,@StartDate))
  END

样本数据

表名


Col1  | Col2  | OrgID | DateRange|
ABC1  |100    |1      |Jan-2014  |
ABC2  |200    |2      |Feb-2014  |
ABC1  |300    |3      |Jan-2014  |
ABC2  |400    |1      |Feb-2014  |
ABC1  |100    |2      |Mar-2014  |
ABC2  |200    |3      |Mar-2014  |
--------------------------------------

这是过去 3 个月的报告,其中包含复杂的计算。如果您注意到 table_Name 仅包含 DateRange,我必须在此基础上在列中创建 Last 3 Months 数据,并根据上述查询获取的数据(即 Month1、Month2 等),必须执行数学运算。这就是我选择 CTE 的原因。

我能够生成结果,但唯一的问题是每列都有重复的行,因为每个 CTE 都有 Group By。

如果他们有任何替代方案,请告诉我!!!!

提前致谢!!!

【问题讨论】:

  • 您能否创建一个包含所有所需功能的新程序?如果是,请分享程序代码。
  • @Horaciux:请检查已编辑的查询。
  • 您可以为表 Table_Name 添加一些示例数据吗?
  • 我已经更新了样本数据!!!希望对你有帮助
  • 你想达到什么目的?你期待什么结果?不管是什么,这个查询似乎太复杂了。此外,同一张表的多次扫描、字符串操作等都会导致性能很差

标签: sql sql-server tsql common-table-expression


【解决方案1】:

您可能应该在 GROUP BY 子句中的每个列上加入 CTE-s,例如:

FROM CTE3
JOIN CTE1 ON CTE1.Parameter=CTE3.Parameter AND CTE1.OrgID=CTE3.OrgID AND CTE1.DateRange=CTE3.DateRange
JOIN CTE2 ON CTE2.Parameter=CTE3.Parameter AND CTE2.OrgID=CTE3.OrgID AND CTE2.DateRange=CTE3.DateRange

(假设这些列不允许 NULL)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    相关资源
    最近更新 更多