2017-12-28 13 views
1

私は、それぞれ独自の行にある製品の車両適合情報の大きなデータセットを持っています。 重複している各エントリの最小年と最大年だけを選択するクエリを作成するのに苦労しています。 は例えば、私は、次のようなデータを持っている:私はデータを保持して心配していないです車両適合データが重複して重複している年

fromyear toyear makename modelname submodelname wheelbase BedLength BedTypeName bodytype note1 Note2 note3 partterminologyname exppartno 
2008 2012 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807 
2010 2010 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807 
2014 2017 Chevrolet Silverado 1500 LT NULL 78.00 Fleetside NULL Black NULL NULL Truck Bed Mat 37807 

をので、私は最小と最大の年の選択が、

のようなものを追加することによって、UPDATEクエリに私のフォーカスを移動しました
(SELECT MIN(p2.fromyear) 
FROM prod AS p2 
WHERE p1.fromyear > 0 
AND p2.toyear >= p1.fromyear 
AND p2.fromyear < p1.fromyear 
AND ISNULL(p2.makename, '') = ISNULL(p1.makename, '') 
AND ISNULL(p2.modelname, '') = ISNULL(p1.modelname, '') 
AND ISNULL(p2.submodelname, '') = ISNULL(p1.submodelname, '') 
AND ISNULL(FLOOR(p2.wheelbase), 0) = ISNULL(FLOOR(p1.wheelbase), 0) 
AND ISNULL(FLOOR(p2.BedLength), 0) = ISNULL(FLOOR(p1.BedLength), 0) 
AND ISNULL(p2.BedTypeName, '') = ISNULL(p1.BedTypeName, '') 
AND ISNULL(p2.bodytype, '') = ISNULL(p1.bodytype, '') 
AND ISNULL(p2.note1, '') = ISNULL(p1.note1, '') 
AND ISNULL(p2.Note2, '') = ISNULL(p1.Note2, '') 
AND ISNULL(p2.note3, '') = ISNULL(p1.note3, '') 
AND ISNULL(p2.exppartno, '') = ISNULL(p1.exppartno, '')) AS newfrom 

は、クエリが過剰な時間(150,000行以上のテーブルから取り出される)で実行されるようにします。 年をマージするためにUPDATEを実行した後、重複する行を削除するだけで済みます。

所望の結果は、このモデルのために2行のみを返します、2008年から2012年と2014年から2017年には

私のオリジナルのアイデアは、単にMIN(fromyear)とMAX(toyear)を選択するには、しかし、これは私を残しました。 2013年の無効年をオプションとして持つ問題。

このような重複年を処理するためのクエリを作成する簡単な方法はありますか?検索で見つかったものは、複数の列のデータを照合する必要はありませんでした。

+1

更新後にテーブルがどのように見えるかを表示することができれば非常に役に立ちます(?を選択してください)。ここで実際に何をしたいのかははっきりしていません。 –

答えて

0

次のように私は(元データにおける年間の全範囲をカバーするために)シーケンシャル年のリストで、日付テーブルに参加することをお勧め:

year 
----- 
... 
2008 
2009 
2010 
2011 
2012 
2013 
2014 
2015 
2016 
2017 
... 

だから、これまでにあなたのソーステーブルに参加行が重複した年を排除するために

その後
year fromyear toyear vehicle_descriptor 

2008 2008  2012 Chevrolet... 
2009 2008  2012 Chevrolet... 
2010 2008  2012 Chevrolet... 
2011 2008  2012 Chevrolet... 
2012 2008  2012 Chevrolet... 

2010 2010  2010 Chevrolet... 

2014 2014  2017 Chevrolet... 
2015 2014  2017 Chevrolet... 
2016 2014  2017 Chevrolet... 
2017 2014  2017 Chevrolet... 

グループ(または個別の選択):表ON (year >= fromyear AND year <= toyear)は、以下の結果が得られます。 (私は一意にあなたの元データで車両を識別すべての列の省略形として「vehicle_descriptor」を使用しています。)

を重複排除された結果では、次のように列を追加します。

(year - ROW_NUMBER() OVER (PARTITION BY vehicle_descriptor ORDER BY year ASC)) AS year_group 

これは、生産します毎年固有の数字または連続した年のシーケンス

year fromyear toyear veicle_descriptor row_number     year_group (year - row_number) 

2008 2008  2012 Chevrolet...  1       2007 
2009 2008  2012 Chevrolet...  2       2007 
2010 2008  2012 Chevrolet...  3       2007 
2011 2008  2012 Chevrolet...  4       2007 
2012 2008  2012 Chevrolet...  5       2007 

2010 2010  2010 Chevrolet...  (this row removed as year 2010 is a duplicate) 

2014 2014  2017 Chevrolet...  6       2008 
2015 2014  2017 Chevrolet...  7       2008 
2016 2014  2017 Chevrolet...  8       2008 
2017 2014  2017 Chevrolet...  9       2008 

最後に、あなたはこのyear_groupを持っていたら、単にグループあなたは、もともと想定の方法で行、year_group vehicle_descriptorによると、およびMIN(年)とMAX(年)を選択します。

year_groupの値は特に重要ではありませんが、最終結果には保持されません。シーケンスを区別するためだけにあります。これは、年の順番に不連続があるたびに増分するため(不連続量で増分するため)に機能します。

私はそれを満足に説明してくれることを願っています。私はデスクトップPCではないので、私は手ですべてを書きました!不明な点がある場合、またはコード例が必要な場合は、お知らせください。お返事します。

+1

スティーブ、これは非常に有用な情報であり、年を分割して重複を削除する素晴らしいアイデアでした!私が気づいていなかった1つのトリックは、PARTITION BYでのOVERの使用でした。年 - ROW_NUMBERをとるというこのアイデアは、年々の格差を抱えてグループ化するためのエレガントなソリューションでした。これは3つの連鎖CTEの組み合わせで、私の問題に完全な解決策を提供しました。 – user9147574

関連する問題