我们有一个非常规范化的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:
没有modelResults或Reviews(在这种情况下返回的所有内容都是CustID)
最近评分的模型(Max(RunDate))无视评论
最近评分的模型(Max(RunDate))已经过审核
通常有三种输出
CustomerID,MostRecentScore,MostRecentReviewedScore,Model和MaxDate
CustomerID,MostRecentScore,Model和MaxDate
客户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
答案 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()