0

これはばかげているように聞こえるかもしれませんが、異なるサイズのテーブルからのデータを処理する関数を作成したいと思います。

私がそのような最初のテーブルを持っているとしましょう:

ID    IRR     M0    M1
----------------------
 1      0    -10     5
 2      0    -20    10
 3      0   -100   100
 4      0    -10     0

そしてそのような2番目のテーブル:

ID    IRR     M0    M1    M2
----------------------------
 1      0    -10     5    60
 2      0    -20    10     0
 3      0   -100   100   400
 4      0    -10     0    10

両方のテーブルのデータを処理できる関数を作成したいと思います。

最初の列にはID、2番目のIRRが含まれ、残りの列には特定の月のキャッシュフローが保持されることを知っています。

関数は、最初の2列ではなくすべての列を処理し、結果を2番目の列に格納できる必要があります。

特定のテーブルからすべての列を取得できることはわかっています。

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.columns 
WHERE TABLE_NAME = 'First_Table'

これらの列を行として返す関数を作成したいときに問題が発生します。

次のような関数を作成できます。

CREATE FUNCTION UnpivotRow (@TableName  varchar(50), @FromWhichColumn int, @Row int)
RETURNS @values TABLE
(
    id INT IDENTITY(0, 1),
    value DECIMAL(30, 10)
)
...

しかし、この関数はどのように見えるべきでしょうか?

この種の処理テーブルの理想は次のようになります。

ProjectID    TimePeriod    Value
--------------------------------
        1             0      -10
        1             1        5
        2             0      -20
        2             1       10
        3             0     -100
        3             1      100
        4             0      -10
        4             1        0

列の数を知らずにテーブル全体のピボットを解除する必要があります。


編集: これが関数内で実行できない場合は、おそらくプロシージャ内ですか?

4

1 に答える 1

2

これは、動的SQLを使用して実行できますUNPIVOT

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colTP as  NVARCHAR(MAX)

select @cols = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('table1') and
               C.name like 'M%'
         for xml path('')), 1, 1, '')


set @query = 'SELECT id, 
              replace(timeperiod, ''M'', '''') timeperiod, 
              value
              from table1
            unpivot 
            (
               value
               for timeperiod in (' + @cols + ')
            ) u '

exec(@query)

SQL FiddlewithDemoを参照してください。

このソリューションは、ストアドプロシージャに配置する必要があります。

于 2012-08-24T11:55:23.463 に答える