我在SQL Server中使用交叉表查询时遇到问题。
假设我有以下数据:
| ScoreID | StudentID | Name | Sex | SubjectName | Score |
------------------------------------------------------------------
| 1 | 1 | Student A | Male | C | 100 |
| 2 | 1 | Student A | Male | C++ | 40 |
| 3 | 1 | Student A | Male | English | 60 |
| 4 | 1 | Student A | Male | Database | 15 |
| 5 | 1 | Student A | Male | Math | 50 |
| 6 | 2 | Student B | Male | C | 77 |
| 7 | 2 | Student B | Male | C++ | 12 |
| 8 | 2 | Student B | Male | English | 56 |
| 9 | 2 | Student B | Male | Database | 34 |
| 10 | 2 | Student B | Male | Math | 76 |
| 11 | 3 | Student C | Female | C | 24 |
| 12 | 3 | Student C | Female | C++ | 10 |
| 13 | 3 | Student C | Female | English | 15 |
| 14 | 3 | Student C | Female | Database | 40 |
| 15 | 3 | Student C | Female | Math | 21 |
| 16 | 4 | Student D | Female | C | 17 |
| 17 | 4 | Student D | Female | C++ | 34 |
| 18 | 4 | Student D | Female | English | 24 |
| 19 | 4 | Student D | Female | Database | 56 |
| 20 | 4 | Student D | Female | Math | 43 |
我想查询显示结果如下:
| StuID| Name | Sex | C | C++ | Eng | DB | Math | Total | Average |
| 1 | Student A | Male | 100| 40 | 60 | 15 | 50 | 265 | 54 |
| 2 | Student B | Male | 77 | 12 | 56 | 34 | 76 | 255 | 51 |
| 3 | Student C | Female | 24 | 10 | 15 | 40 | 21 | 110 | 22 |
| 4 | Student D | Female | 17 | 34 | 24 | 56 | 43 | 174 | 34.8 |
我如何查询以显示这样的输出?
笔记:
主题名称:
将根据学生学习的学科而有所不同。
请访问http://sqlfiddle.com/#!6/2ba07/1来测试此查询。
有两种方法可以执行PIVOT
对值进行硬编码的静态方法和执行时确定列的动态方法。
即使您想要一个动态版本,有时也更容易从静态版本开始,PIVOT
然后朝着动态版本迈进。
静态版本:
SELECT studentid, name, sex,[C], [C++], [English], [Database], [Math], total, average
from
(
select s1.studentid, name, sex, subjectname, score, total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
) x
pivot
(
min(score)
for subjectname in ([C], [C++], [English], [Database], [Math])
) p
参见带有演示的SQL Fiddle
现在,如果您不知道将要转换的值,则可以为此使用Dynamic SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(SubjectName)
from Score
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT studentid, name, sex,' + @cols + ', total, average
from
(
select s1.studentid, name, sex, subjectname, score, total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
) x
pivot
(
min(score)
for subjectname in (' + @cols + ')
) p '
execute(@query)
参见带有演示的SQL Fiddle
两种版本将产生相同的结果。
只是为了完善答案,如果您没有PIVOT
函数,则可以使用CASE
和聚合函数获得此结果:
select s1.studentid, name, sex,
min(case when subjectname = 'C' then score end) C,
min(case when subjectname = 'C++' then score end) [C++],
min(case when subjectname = 'English' then score end) English,
min(case when subjectname = 'Database' then score end) [Database],
min(case when subjectname = 'Math' then score end) Math,
total, average
from Score s1
inner join
(
select studentid, sum(score) total, avg(score) average
from score
group by studentid
) s2
on s1.studentid = s2.studentid
group by s1.studentid, name, sex, total, average
参见带有演示的SQL Fiddle
问题内容: 我目前有一个使用以下sql的硬编码视图: 我的问题是是否可以从角色表中的记录动态生成角色列。 问题答案: 您 可以 做您想做的事,但是我不确定 为什么 要这么做。获得动态列别名后,如何计划引用它们?也就是说,如果您从数据库中提取列别名,那么您将如何使用它们呢?我可能错过了您提出问题的原因。 无论如何,我假设您具有这样的结构: 由此,您可以获得有关用户及其角色的信息: 您还可以为特定角色
问题内容: 我有这个表视图 如何创建将在Oracle 10g中提供此透视图视图的查询? 有没有办法动态地做到这一点?我看到了很多方法(解码,PL / SQL循环,联合,11g数据透视) 但根据上述示例,我尚未找到适合我的方法 编辑 :我不知道在开发时间产品的数量或类型,所以这必须是动态的 问题答案: Oracle 11g是第一个支持PIVOT / UNPIVOT的,因此您必须使用: 您可以使用DE
问题内容: 我已经搜索过,但没有找到(或理解!)如何做我需要做的事情。我问这个问题有点愚蠢,因为还有其他例子,但是我只是不明白…。 这是我认为的数据: 我需要的是: 我一直在修改在这里找到的代码,但是..任何帮助,我们都感激不尽! 问题答案: 您可以通过几种不同的方式将行转换为列。一种实现方法是使用带有CASE表达式的聚合函数: 参见带有演示的SQL Fiddle 或者由于使用的是SQL Serv
问题内容: 我已经徒劳地搜索了很长时间,不得不承认失败并寻求帮助,我正在尝试修改数据透视查询,以从具有以下数据的表中生成结果的动态查询: 为了显示这样的内容,其中页码列取决于用户访问的页面数: 我已经通过对列中的硬编码进行了管理,但是显然我不想继续更改脚本以容纳越来越多的页面。 到目前为止,我有一些类似的东西: 任何帮助或正确方向的指点将不胜感激! 提前致谢! 问题答案: 我所看到的关于动态枢轴的
问题内容: 我试图找到一种方法来返回具有动态列数的记录集。我可以编写一个查询来生成需要的列名列表,如下所示: 这将返回一个简短的列表,例如’poke’,’prod’,’hit’,’drop’等。然后,我希望生成一个表,其中显示了一系列测试,其中每个测试都在其中运行。每天早晨,我们查看开发人员的工作并对其进行戳戳和刺戳,以便每天进行每次测试。我可以静态编写此查询: 但是,这是硬编码到我们每天运行的测
问题内容: 我有下面的代码,我在布尔查询中做多个必须的。在这里,我将在字段“地址”中传递必填项查询。现在,该IP地址将以其他api的列表的形式出现在我的面前,我必须将列表中的所有IP作为必填项查询传递给我。在这里,我没有办法创建QueryBuilder时如何动态传递地址值。 请提出建议。 问题答案: 您可以使用条件查询为单个字段传递多个值。创建一个字符串数组或集合。并将其传递给条款查询。 希望能帮