2

私は以下のようなものを返すSQLクエリを持っています:

Rating as at    Rating type    Rating
--------------------------------------
6/7/2012        Type1          A
6/7/2012        Type2          A+
6/7/2012        Type3          B
8/7/2012        Type1          C
8/7/2012        Type2          C+
8/7/2012        Type3          B
8/7/2012        Type4          A

ご覧のとおり、評価タイプは動的であり、ピボットで表示したいのですが、これを実現する方法がわかりません。私が望む最終結果は次のようなものです:

Rating as at    Type1   Type2   Type3   Type4
6/7/2012        A       A+       B
8/7/2012        C       C       C+       A

SQLを使用してこれを実現する方法を知りたいです。または、LINQ C#を使用してどのように行うのが最善ですか?

助けていただければ幸いです。ありがとう。

4

3 に答える 3

1

以下のOPのコメントに基づいて回答を更新-この更新により、結果が文字の成績に変換されるようになります

以下では、SQL Serverのピボット演算子(MSDN)とEXECステートメント(MSDN)を組み合わせて使用​​しています。

T-SQLソリューションは、完全に動的な列を処理します。

--Create a temp table to hold values
CREATE TABLE #MyTable (
[Rating as at] DATE,
[Rating type] Nvarchar(30),
Rating FLOAT )

INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('6/7/2012','Type1', 1)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('6/7/2012','Type2', 3)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('6/7/2012','Type3', 5)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('8/7/2012','Type1', 5)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('8/7/2012','Type2', 2)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('8/7/2012','Type3', 4)
INSERT INTO #MyTable ([Rating as at],[Rating type],Rating) VALUES ('8/7/2012','Type4', 1)
SELECT DISTINCT [Rating type] INTO #MyTableDistinct FROM #MyTable

--Create a string of dynamic fields
DECLARE @MyVar1 nvarchar(max),@MyVar2 nvarchar(max)
SELECT @MyVar1 = COALESCE(@MyVar1,'') + '[' + [Rating type] + ']' + ', '  FROM #MyTableDistinct 
SELECT @MyVar1 = LEFT(@MyVar1, LEN(@MyVar1) - 1)

--Create a string of dynamic CASE statements to be used to convert pivoted results to letter grades
--Update the CASE steatement to handle different grade types
SELECT @MyVar2 = COALESCE(@MyVar2,'') + 'CASE WHEN [' + [Rating type] + '] IS NULL THEN ''N/A'' WHEN [' + [Rating type] + '] > 4 THEN ''A'' WHEN [' + [Rating type] + '] > 3 THEN ''B'' WHEN [' + [Rating type] + '] > 2 THEN ''C'' ELSE ''F'' END AS [' + [Rating type] + '], '  FROM #MyTableDistinct 
SELECT @MyVar2 = LEFT(@MyVar2, LEN(@MyVar2) - 1)

--Build a SQL string to be later execute
--This is where all of the PIVOT magic happens
DECLARE @MySQLStatement nvarchar(max)
SET @MySQLStatement = 'SELECT [Rating as at],' + @MyVar1 +  ' INTO #MyPivotTable FROM 
    (SELECT [Rating as at],[Rating type],Rating from #MyTable) AS p1
    PIVOT (
        avg(Rating) FOR [Rating type] IN (' + @MyVar1 + ') 
    ) as p2;SELECT [Rating as at], ' + @MyVar2 + ' FROM #MyPivotTable;DROP TABLE #MyPivotTable;'

--Execute the SQL string
EXEC(@MySQLStatement)


DROP TABLE #MyTableDistinct
DROP TABLE #MyTable
于 2012-07-08T11:25:47.743 に答える
1
select "Rating as at", 
max(case when Rating_Type = 'Type1' then Rating else 0 end) as Type1,
max(case when Rating_Type = 'Type2' then Rating else 0 end) as Type2,
max(case when Rating_Type = 'Type3' then Rating else 0 end) as Type3,
max(case when Rating_Type = 'Type4' then Rating else 0 end) as Type4,
from Table
group by "Rating as at"
于 2012-07-08T00:56:28.650 に答える
0

持っているデータをそのまま取得し、linq を使用して変換するのが最も簡単な場合があります。実行時にこれを行う必要があるため、Type1、Type2 などのプロパティを持つオブジェクトを実際に取得することはできませんが、値の配列を取得できます。最初にすべての評価タイプのリストを取得してから、データをピボットするための 2 つ目のクエリを作成する必要があります。このようなもの:

public class SomeClass
{
    public DateTime RatingDate;
    public string RatingType;
    public int Rating;
}

var data = new SomeClass[]
{
    new SomeClass() { RatingDate = DateTime.Parse("6/7/2012"), RatingType = "Type1", Rating = 1 },
    new SomeClass() { RatingDate = DateTime.Parse("6/7/2012"), RatingType = "Type2", Rating = 3 },
    new SomeClass() { RatingDate = DateTime.Parse("6/7/2012"), RatingType = "Type3", Rating = 5 },
    new SomeClass() { RatingDate = DateTime.Parse("8/7/2012"), RatingType = "Type1", Rating = 5 },
    new SomeClass() { RatingDate = DateTime.Parse("8/7/2012"), RatingType = "Type2", Rating = 2 },
    new SomeClass() { RatingDate = DateTime.Parse("8/7/2012"), RatingType = "Type3", Rating = 4 },
    new SomeClass() { RatingDate = DateTime.Parse("8/7/2012"), RatingType = "Type4", Rating = 1 }
};

var ratingTypes = data.Select(i => i.RatingType)
    .Distinct().OrderBy(i => i).ToArray();

var results = data.GroupBy(i => i.RatingDate)
    .Select(g => new { RatingDate = g.Key, Ratings = ratingTypes.GroupJoin(g, o => o, i => i.RatingType, (o, i) => i.Select(x => x.Rating).Sum()).ToArray() })
    .ToArray();

必要に応じて、グループ結合を別の関数に分割して、もう少し読みやすくすることができます。

Func<IEnumerable<SomeClass>, int[]> func
    = group => ratingTypes.GroupJoin(group, o => o, i => i.RatingType, (o, i) => i.Select(x => x.Rating).Sum()).ToArray();

var results = data.GroupBy(i => i.RatingDate)
    .Select(g => new { RatingDate = g.Key, Ratings = func(g) })
    .ToArray();
于 2012-07-09T01:20:02.897 に答える