Tシャツ。SQLはまた別の2種類が3年連続受賞者を探しています。
2696 ワード
このテーマは3年連続の受賞者を探します。まずテーブルを作成して、データを塗りつぶします。
1第一の方式:T_を使う。SQLのキーワードアプリです。
アプリには2つの入力パラメータがあります。左入力と右入力、右入力は関数としてもいいし、サブクエリーとしてもいいです。左に入力した行ごとに、右入力で計算し、結果をまとめます。
Prizeの各行については、CROSS APPLYの左入力として右入力で名前を検索します。受賞年は大きいですが、受賞年は3年以内です。見つけられるなら、
結果表の左に該当するギルドが3行以上入力されます。次に名前と月別にグループ分けして、3より大きいCOUNTを見つければいいです。以下のとおりです
2番目の方法は、CTEを使用して再帰的にクエリを行う。以下のとおりです
現在が大きい。このような方式の鍵はCASE文で、現在の行のyearより1大きい行を見つけたら、countを更新して、現在の行のcount+1にします。さもなければ、現在の行は連続して受賞しているyearではないと説明して、countを使用します。
カウントは1に戻ります。最後にcountが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以上の行を検索するだけです。