0

以下に示す例の表があり、人とその生年月日と死亡年数がリストされています(9999は生きている人を示します)。

person | born | died
1      | 2001 | 9999
2      | 2002 | 2003
3      | 2002 | 2008
4      | 2004 | 2009
5      | 2005 | 9999
6      | 2010 | 2012

何年にもわたって人口を計算したいと思います。上記の例では、出力は次のようになります。行の最後にある生きている人のリストは、デモンストレーションのみを目的としたものであり、出力では必要ありません。

year | population
2001 | 1                  (1)
2002 | 3                  (1,2,3)
2003 | 2                  (1,3)
2004 | 3                  (1,3,4)
2005 | 4                  (1,3,4,5)
2006 | 4                  (1,3,4,5)
2007 | 4                  (1,3,4,5)
2008 | 3                  (1,4,5)
2009 | 2                  (1,5)
2010 | 3                  (1,5,6)
2011 | 3                  (1,5,6)
2012 | 2                  (1,5)

これでC#プログラムを作成し、元のテーブルの各行をループして、生年と死亡年の間にある各年の人口数を増やすことができます。ただし、完全にTSQLスクリプトで実行する必要があります。私はTSQLの初心者です。どうすればいいですか?同様の問題がすでに議論されている場合は、それを指摘してください。ありがとうございました。

4

1 に答える 1

1
DECLARE @t TABLE(person INT, born INT, died INT);

INSERT @t VALUES
(1,2001,9999),
(2,2002,2003),
(3,2002,2008),
(4,2004,2009),
(5,2005,9999),
(6,2010,2012);

DECLARE @start INT, @end INT;

SELECT @start = 2001, @end = 2012;

;WITH n(y) AS 
(
  SELECT TOP (@end - @start + 1) 
    @start - 1 + ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_objects
)
SELECT 
  [year] = n.y, 
  population = SUM(CASE WHEN n.y >= t.born AND n.y < t.died THEN 1 ELSE 0 END) 
FROM n CROSS JOIN @t AS t GROUP BY n.y;

結果:

year    population
----    ----
2001    1
2002    3
2003    2
2004    3
2005    4
2006    4
2007    4
2008    3
2009    2
2010    3
2011    3
2012    2

FWIW私はまさにこのことについてのブログシリーズを始めました:

http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1

于 2013-01-16T19:42:13.677 に答える