c# - SQL Server 2000 交叉表多表

标签 c# asp.net sql sql-server tsql

我有 4 个表,我想动态生成输出,但我需要表 gradesport 将其行转换为列。下表提供了示例数据。

学生

enter image description here

等级

enter image description here

注册

enter image description here

运动

enter image description here

这是我想要的输出:

enter image description here

输出显示了在 91 老师下注册的学生,并显示了所有运动(作为列)及其在 sy 2014 上的相应成绩。同样,我们使用的是 SQL Server 2000(我想我应该为此感到难过)。我已经尝试了很多在互联网上找到的查询,但它不起作用..而且通常它是静态生成的(如果您已经知道要显示哪些列)。

Cross Tab 本身有点方便,我正在使用多个表格使其变得更加复杂。我已经有 3 个多月的时间遇到​​这个问题了,但我仍然没有成功达到我想要的输出。顺便说一下,我在 ASP.Net 中的 SqlDataSource 上对其进行编码,并将其绑定(bind)到 GridView 上。

最佳答案

SQL 2000 版本:

DECLARE @dynamicCols VARCHAR(8000);
SET @dynamicCols = '';

SELECT @dynamicCols = @dynamicCols+ 
       ', SUM(CASE WHEN sport.sportid='''+sportid+''' THEN grade.grade END) AS ['+sport+'] '
FROM sport

EXECUTE ( 
      'SELECT student.idnumber AS ID, student.student AS Student '
      +@dynamicCols+
      'FROM student
       JOIN grade on student.idnumber=grade.idnumber
       JOIN enrol on enrol.sportid=grade.sportid
       JOIN sport on sport.sportid=enrol.sportid 
       WHERE enrol.teacher=''91'' AND enrol.sy=''2014''
       GROUP BY student.idnumber, student.student
       ORDER BY student.student')

原始答案

好的,既然没有人站出来,我将向您展示我将如何动态地做到这一点。

基于 YOusaFZai's template of doing it by hand ,首先在选择列表中创建动态项,然后将它们合并到 select 语句的其余部分,最后执行此动态语句:

DECLARE @sqlSTR VARCHAR(MAX);
DECLARE @dynamicCols VARCHAR(MAX);

SELECT @dynamicCols = 
(
  SELECT ', SUM(CASE WHEN sport.sportid='''+sportid+''' THEN grade.grade END) AS ['+sport+'] '
  FROM sport
  FOR XML PATH('')
)

--PRINT @dynamicCols

SELECT @sqlSTR = 
      'SELECT student.idnumber AS ID, student.student AS Student '+@dynamicCols+
      'FROM student
       JOIN grade on student.idnumber=grade.idnumber
       JOIN enrol on enrol.sportid=grade.sportid
       JOIN sport on sport.sportid=enrol.sportid 
       WHERE enrol.teacher=''91'' AND enrol.sy=''2014''
       GROUP BY student.idnumber, student.student
       ORDER BY student.student'

EXEC(@sqlSTR)

高级

有时您可能会预料到坏数据,您可以保护自己。例如,如果成绩表可能包含不在运动表中的运动 ID,您可以像下面这样更改第一个查询以在结果中包含错误数据:

SELECT @dynamicCols = 
(
  SELECT DISTINCT ', SUM(CASE WHEN grade.sportid='''+grade.sportid+''' THEN grade.grade END) AS ['+ISNULL(sport.sport,'ILLEGAL ID #'+grade.sportid)+'] '
  FROM grade
  LEFT JOIN sport ON sport.sportid = grade.sportid
  FOR XML PATH('')
)

关于c# - SQL Server 2000 交叉表多表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23484860/

相关文章:

c# - 在 ASP.Net 中呈现 "partial"页面? (没有 <html> 等)

sql - 如何查询链接服务器中的#TempTable

c# - 如何在 .NET Core 中撤消 Entity Framework Update-Database

c# - 是 new Thread(() => {//logic}).Start();可接受在 Web 应用程序 page_load 中执行逻辑 "asynchronously"

c# - 创建一个仅包含当前Region的新RegionManager

asp.net - 完全替换 Swashbuckle UI

javascript - 如何下载服务器在 Ajax 调用中返回的文件?

ASP.NET MVC 应用程序分析

sql - Postgres 执行合并中的所有子查询

sql - 合并两个 CSV 并整理数据