1

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

涉及的表格有: 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,但不一定是 Review

每个 Review(vw_exp_review) 都有一个 CustomerID 和 modelresultsreviewid

查询的目标是查找具有相同 CustomerID 和 ModelID 的 CustomerID、Scores、Models 和 RunDates,其中:

  1. 没有模型结果或评论(在这种情况下,返回的只是一个 CustID)

  2. 最近得分的模型 (Max(RunDate)) 与评论无关

  3. 已审查的最近得分模型 (Max(RunDate))

一般有3种输出

  1. CustomerID、MostRecentScore、MostRecentReviewedScore、Model 和 MaxDate

  2. CustomerID、MostRecentScore、Model 和 MaxDate

  3. 客户ID

到今天为止,我仍在使用以下内容:

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

4

1 回答 1

2

您可以使用CTE代替临时表。这些可以很容易地用于将您的查询合并为一个,例如:

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()

于 2013-01-15T19:54:37.260 回答