从select语句创建一个View,该语句在T-SQL中使用多个临时表来消除对临时表的需要

时间:2013-01-15 18:52:48

标签: tsql view temp-tables

我们有一个非常规范化的SQL 2005数据库。问题是我需要一个查询来对数据进行去规范化并将其放入视图中。目前,我有一个获得所需结果集的查询;但我使用三个临时表来执行此操作并需要切换到视图以通过第三方报告软件运行SQL,我们不希望能够创建临时表。由于视图需要是单个select语句;我正在寻求帮助,将我丑陋的查询变成一个可以作为视图的单个select语句。

所涉及的表格是: ModelResults [CustomerID,ModelID,RunDate,Score,ModelResultID(= modelresultsreviewid)]

Customers [CustomerID]

Models [ModelName,ModelID]

所涉及的意见如下: (这是所有具有评论的ModelResults的集合) vw_exp_review [CustomerID,modelresultsreviewid]

他们的关系如下:

每位客户都有一个CustomerID;但不一定是ModelResult或Review或者

每个模型都有一个ModeID和ModelName

每个ModelResult都有CustomerID,ModelID,RunDate和Score,但不一定是评论

每次评论(vw_exp_review)都有一个CustomerID和modelresultsreviewid

查询的目标是找到所有具有相同CustomerID和ModelID的CustomerID,分数,模型和RunDates:

  1. 没有modelResults或Reviews(在这种情况下返回的所有内容都是CustID)

  2. 最近评分的模型(Max(RunDate))无视评论

  3. 最近评分的模型(Max(RunDate))已经过审核

  4. 通常有三种输出

    1. CustomerID,MostRecentScore,MostRecentReviewedScore,Model和MaxDate

    2. CustomerID,MostRecentScore,Model和MaxDate

    3. 客户id

    4. 截至今天,我仍在使用以下内容:

      DROP TABLE #_T1
      
      -- MostRecentScore
      
      SELECT CustomerID,ModelID,ModelResultID,RunDate,Min(Score) as MinScore
      
      INTO #_T1
      
      FROM ModelResults m1 WITH (NOLOCK)
      
      WHERE RunDate IN (SELECT MAX(m.RunDate) FROM ModelResults m GROUP BY m.CustomerID)
      
      GROUP BY
      
      CustomerID,ModelID,ModelResultID,RunDate
      
      
      
      
      DROP TABLE #_T2
      
      --MostRecentReviewedScore
      
      SELECT CustomerID,ModelID,RunDate,MIN(Score) AS MinScore
      
      INTO #_T2
      
      FROM ModelResults m1 WITH (NOLOCK)
      
      WHERE RunDate IN (SELECT MAX(RunDate) 
      
                      FROM ModelResults t JOIN vw_exp_review r ON 
      
                                          r.modelresultsreviewid = t.ModelResultID
      
                      GROUP BY t.CustomerID)
      
      GROUP BY CustomerID,ModelID,RunDate
      
      
      
      DROP TABLE #_T3
      
      --MostRecentModelResultDate
      
      SELECT c.CustomerID,MAX(RunDATE) as MAXDate
      
      INTO #_T3
      
      FROM ModelResults mr WITH (NOLOCK)
      
      RIGHT OUTER JOIN Customers C
      
      ON mr.CustomerID = c.CustomerID
      
      GROUP BY c.CustomerID
      
      
      
      SELECT t3.CustomerID,t1.MinScore as MostRecentScore,
      
      t2.MinScore as MostRecentReviewedScore,m.Model as ModelName,
      
      t3.MaxDate
      
      FROM #_T1 t1
      
      LEFT OUTER JOIN #_T2 t2
      
      ON t1.CustomerID = t2.CustomerID AND t1.ModelID = t2.ModelID
      
      RIGHT OUTER JOIN #_T3 t3
      
      ON t1.CustomerID = t3.CustomerID
      
      LEFT OUTER JOIN Models m
      
      ON t1.ModelID = m.ModelID
      
      
      ORDER BY
      t3.CustomerID
      

      示例输出:

      CustID,MostRecentScore,MostRecentReviewed,ModelName,MaxDate

      8,2.36,4.59,Unrated Scorecard,2011-08-10 15:08:53.807

      1361,2.76,NULL,SET Rated,2010-04-20 20:48:39.530

      1362,NULL,NULL,NULL,NULL

1 个答案:

答案 0 :(得分:1)

您可以使用CTEs代替临时表。这些可以很容易地用于视图中将您的查询组合成一个,例如:

CREATE VIEW MYVIEW
AS
    WITH T1
    AS
    (
    -- MostRecentScore
      SELECT CustomerID,ModelID,ModelResultID,RunDate,Min(Score) as MinScore
      FROM ModelResults m1 WITH (NOLOCK)
      WHERE RunDate IN (SELECT MAX(m.RunDate) FROM ModelResults m GROUP BY m.CustomerID)
      GROUP BY
      CustomerID,ModelID,ModelResultID,RunDate
    )
    ,T2
    AS
    (
      --MostRecentReviewedScore
      SELECT CustomerID,ModelID,RunDate,MIN(Score) AS MinScore
      FROM ModelResults m1 WITH (NOLOCK)
      WHERE RunDate IN (SELECT MAX(RunDate) 
                        FROM ModelResults t JOIN vw_exp_review r ON 
                        r.modelresultsreviewid = t.ModelResultID
                        GROUP BY t.CustomerID)
      GROUP BY CustomerID,ModelID,RunDate
    )
    ,T3
    AS
    ( 
      SELECT c.CustomerID,MAX(RunDATE) as MAXDate
      FROM ModelResults mr WITH (NOLOCK)
      RIGHT OUTER JOIN Customers C
      ON mr.CustomerID = c.CustomerID
      GROUP BY c.CustomerID
    )
    SELECT 
      t3.CustomerID,t1.MinScore as MostRecentScore,
      t2.MinScore as MostRecentReviewedScore,m.Model as ModelName,
      t3.MaxDate
    FROM T1 t1
    LEFT OUTER JOIN T2 t2
      ON t1.CustomerID = t2.CustomerID AND t1.ModelID = t2.ModelID
    RIGHT OUTER JOIN T3 t3
      ON t1.CustomerID = t3.CustomerID
    LEFT OUTER JOIN Models m
      ON t1.ModelID = m.ModelID
    ORDER BY
    t3.CustomerID

SQL-Fiddle没有附加,因此未经过测试,因为OP中没有演示数据。

请注意,每次执行CTE都会被执行。您也可以写一个UDF返回包含您数据的表格。在该函数中,您仍然可以像在OP中一样使用临时表,并将视图创建为select * from myfunction()