sql - SQLを介して動的列を割り当てる

sql sql-server

2つの日付間の減算の前の月数に従って列をマップする必要があります。

例:2012-10-01-2010-10-01 = 24

(一時テーブルに挿入するために)24列を割り当てる必要があります。01.10.2012から01.10.2010までのすべての月の名前=> 10月、11月、..... 10月。

各列は次のような月を表します:

10月11月12月1月2月3月4月5月6月7月8月9月10月11月12月1月2月3月4月5月6月7月8月9月10月

table_Temporal

City    
Area    
Production => Oct,Nov,Dec...etc...
Yield


わかりました。「生産」という図があり、「収穫の月」と呼ばれる時間に応じて、月ごとの分布を示しています。

例:

生産=>収穫日
100 => '2010/10/02'
200 => '2011 / 11/01'
100 => '2012 / 10/10'

結果セットは



助言がありますか?
答え
このためには、カーソルを使用したり、列を動的に作成したりせずに、単一のテーブルが必要になります。解決策は、結果をピボットして最終出力を取得することです

2010-10  2010-11 2010-12 2011-1...
  50      100     25       70


つまり、年と月の組み合わせが列を一意にし、合計は月全体に対して行われ、正しい列に配置されます。すぐに発生した問題の1つは、PIVOTを使用するときに列名をリストする必要があることです。たとえば... PIVOT (SUM(Harvest)) FOR ([2011-10], [2011-11]...ですが、STUFFXML Pathを使用することで、これをすべて回避できます。

これはあなたができることです、私はTEMPテーブルを使用しましたが、これを変更して実際のテーブルを参照することができます。最初のテーブル:

CREATE TABLE #Test
 (
    [ID] [int] IDENTITY(1,1) NOT NULL,
    TheDate datetime,
    Harvest int
 )


次に、いくつかのダミーデータを挿入します。

INSERT INTO #Test(TheDate, Harvest) VALUES ('10/11/2011', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('10/11/2012', 100)
INSERT INTO #Test(TheDate, Harvest) VALUES ('10/1/2011', 20)
INSERT INTO #Test(TheDate, Harvest) VALUES ('12/11/2011', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('11/11/2011', 50)
INSERT INTO #Test(TheDate, Harvest) VALUES ('11/12/2011', 150)


結果を表示します。

SELECT * FROM #Test


結果は次のとおりです。

ID   TheDate                 Harvest
1   2011-10-11 00:00:00.000 50
2   2012-10-11 00:00:00.000 100
3   2011-10-01 00:00:00.000 20
4   2011-12-11 00:00:00.000 50
5   2011-11-11 00:00:00.000 50
6   2011-11-12 00:00:00.000 150


ここで魔法が起こります:

DECLARE @listCol VARCHAR(2000)
DECLARE @query VARCHAR(4000)

SELECT  @listCol = STUFF((  
                          SELECT DISTINCT
                          ],[' + ltrim(str(YEAR(TheDate))) + 
                          '-' + CAST (MONTH(TheDate) as varchar(50))
                          FROM    
                   #Test
                  ORDER BY 
                '],[' + ltrim(str(YEAR(TheDate))) + '-' + 
                            CAST(MONTH(TheDate) as varchar(50))
                            FOR XML PATH('')
                                    ), 1, 2, '') + ']'
SET @query = 
'SELECT * FROM
      (SELECT 
             ltrim(str(YEAR(TheDate))) + 
             ''-'' + CAST (MONTH(TheDate) as varchar(50)) AS TheCol, 
             Harvest
            FROM 
             #Test
            ) src
        PIVOT (SUM(Harvest) FOR TheCol
        IN ('+@listCol+')) AS pvt'


次に、このクエリを実行します。

EXECUTE (@query)

結果:

2011-10    2011-11     2011-12    2012-10
70          200         50    100


一時テーブルを削除することを忘れないでください

DROP TABLE #Test

テストデータを使用しているので、必要に応じて追加できます。以下はすべてのグラフィック出力です。
関連記事

sql - SQL Serverで動的な列、値、およびデータ型を使用してPIVOTを行うにはどうすればよいですか?

mysql - MySQLの最新の日付のレコードの選択

sql - MS SQLのCONTAINS条件の誤った計画

sql - Doctrine 2 JOINエラー

mysql - 2つの列に一意のインデックスを持つテーブルにINSERT INTO

sql - SQL:テーブルのサブセットの物理サイズを取得する

mysql - MySQLはtable1への挿入時にtable2に行を自動挿入します

python - 可変長期間の最大出力を見つける

sql - データベースの行間の日時の違い

php - Oracleストアドプロシージャから配列結果を取得する方法