1

非常に正規化された SQL 2005 データベースがあります。問題は、データを非正規化してビューに入れるクエリが必要なことです。現在、目的の結果セットを取得するクエリがあります。しかし、私はそのために 3 つの一時テーブルを使用しており、一時テーブルを作成する機能を提供したくないサード パーティのレポート ソフトウェアを介して 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 であるとは限りません

すべてのレビュー (vw_exp_review) には CustomerID と modelresultsreviewid があります

クエリの目的は、すべてが同じ CustomerID と ModelID を持つ CustomerIDs、Scores、Models、および RunDates を見つけることです。

  1. modelResults または Reviews はありません (この場合、返されるのは 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を使用できます。これらをビューで簡単に使用して、クエリを 1 つにまとめることができます。

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

OPにデモデータがないため、SQL-Fiddleが添付されていないため、テストされていません。

CTE はアクセスされるたびに実行されることに注意してください。データを含むテーブルを返すUDFを作成することもできます。関数では、OP のように一時テーブルを使用し、次のようにビューを作成できます。select * from myfunction()

于 2013-01-15T19:54:37.260 に答える