Tシャツ。SQLはまた別の2種類が3年連続受賞者を探しています。

2696 ワード

このテーマは3年連続の受賞者を探します。まずテーブルを作成して、データを塗りつぶします。
;WITH Prize(Name, Year) AS(

	SELECT 'Kim', 2001 UNION ALL

	SELECT 'Tim', 2002 UNION ALL

	SELECT 'Tang', 2002 UNION ALL

	SELECT 'Jack', 2001 UNION ALL

	SELECT 'Juicy', 2001 UNION ALL

	SELECT 'Peff', 2002 UNION All

	SELECT 'Juicy', 2002 UNION ALL

	SELECT 'Kim', 2002 UNION ALL

	SELECT 'Juicy', 2003 UNION ALL

	SELECT 'Peff', 2003 UNION ALL

	SELECT 'Kim', 2003 UNION ALL

	SELECT 'Tim', 2004 UNION ALL

	SELECT 'Juicy', 2004 UNION ALL

	SELECT 'Jack', 2005 UNION ALL

	SELECT 'Eric', 2005 UNION ALL

	SELECT 'Tim', 2005 UNION ALL

	SELECT 'Eric', 2006 UNION ALL

	SELECT 'Peff', 2006 UNION ALL

	SELECT 'Juicy', 2007 UNION ALL

	SELECT 'Eric', 2007 UNION ALL

	SELECT 'Tang', 2007 UNION ALL

	SELECT 'Tang', 2008 UNION ALL

	SELECT 'Peff', 2008 UNION ALL

	SELECT 'Kim', 2008 UNION ALL

	SELECT 'Jack', 2009 UNION ALL

	SELECT 'Tang', 2009 UNION ALL

	SELECT 'Kim', 2009)

	

SELECT * 

INTO dbo.Prize

FROM Prize

ORDER BY Name, Year



CREATE CLUSTERED INDEX cluster_index_main ON dbo.Prize(Name) 
Prize表の列Nameは名前を表し、yearは受賞年を表します。
1第一の方式:T_を使う。SQLのキーワードアプリです。
アプリには2つの入力パラメータがあります。左入力と右入力、右入力は関数としてもいいし、サブクエリーとしてもいいです。左に入力した行ごとに、右入力で計算し、結果をまとめます。
Prizeの各行については、CROSS APPLYの左入力として右入力で名前を検索します。受賞年は大きいですが、受賞年は3年以内です。見つけられるなら、
結果表の左に該当するギルドが3行以上入力されます。次に名前と月別にグループ分けして、3より大きいCOUNTを見つければいいです。以下のとおりです
SELECT DISTINCT Name

FROM(

	SELECT Name, Year, COUNT(LYear) C

	FROM(

		SELECT *

		FROM dbo.Prize P1

		CROSS APPLY(

			SELECT TOP 3 Year LYear

			FROM dbo.Prize P2

			WHERE P1.Name = P2.Name AND P2.Year >= P1.Year AND

				P2.Year - P1.Year <=2

			ORDER BY Year) AS D1

			) AS d2

	GROUP BY Name, Year

) AS D3

WHERE D3.C >=3
 
2番目の方法は、CTEを使用して再帰的にクエリを行う。以下のとおりです
;WITH cte1(name, year, count) AS

(

	SELECT Name, MIN(year), 1

	FROM dbo.Prize

	GROUP BY Name	

	

	UNION ALL

	

	SELECT p.Name, p.Year , 

		CASE 

			WHEN p.Year = c.year + 1 THEN c.count +1

			ElSE 1

		END 

	FROM dbo.Prize p JOIN cte1 c

	ON p.Name = c.name AND p.Year > c.year

)



SELECT DISTINCT name 

FROM cte1

WHERE  count >= 3

ORDER BY name
この再帰的な位置づけの条件は名前によってグループ分けして、受賞年の最小のそれを探し出すことです。次に再帰的に実現される部分です。Prizeテーブルとcteテーブルを接続して、接続の条件は名前が等しいと同時に、新しく加入したのは受賞年比です。
現在が大きい。このような方式の鍵はCASE文で、現在の行のyearより1大きい行を見つけたら、countを更新して、現在の行のcount+1にします。さもなければ、現在の行は連続して受賞しているyearではないと説明して、countを使用します。
カウントは1に戻ります。最後にcountが3以上の行を検索するだけです。