我有一个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#??
帮助将不胜感激。感谢。
答案 0 :(得分: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"
答案 1 :(得分:1)
根据以下OP评论更新了答案 - 此更新现在将结果转换为字母成绩
以下使用SQL Server的Pivot运算符(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
答案 2 :(得分:0)
获取数据可能最简单,并使用linq进行转换。你永远不可能真正得到一个具有Type1,Type2等属性的对象,因为你需要在运行时执行此操作,但是你可以获得一组值。您首先需要获取所有评级类型的列表,然后再进行第二次查询以转动数据。像这样:
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();