2014-05-06 4 views
3

У меня есть 4 таблицы, которые я хочу динамически генерировать вывод, но мне нужны таблицы grade и sport, чтобы их строки были преобразованы в столбцы. В приведенных ниже таблицах приведены примеры данных.SQL Server 2000 Cross Tab Несколько таблиц

студент

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 (и я думаю, что я должен чувствовать себя плохо abo ut it). Я пробовал много запросов, которые я нашел в Интернете, но он не работает .. и обычно он статически сделан (если вы уже знаете, какие столбцы вы хотите отобразить).

Скрипка сама по себе немного удобна, и я делаю ее более сложной с несколькими таблицами. У меня эта проблема уже более 3 месяцев, и мне все еще не удалось достичь желаемого результата. Кстати, я кодирую его на SqlDataSource в ASP.Net и привязываю его на GridView.

+0

Единственного способом сделайте это, если вы не знаете названия спортов, прежде чем рука будет с динамическим sql. Используйте один из приведенных ниже ответов и генерируйте строки сумм и динамически объединяйте строки из таблицы в строковую переменную и выполните ее. – Hogan

+0

Я пробовал делать динамический sql, но он продолжает выскакивать ошибки, как необъявленная переменная, независимо от того, работает ли она с SQL Server 2000? – eirishainjel

ответ

4

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 ' 
     [email protected]+ 
     '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 сначала создать динамические элементы в списке выбора, то объединить их с остальной частью оператора выбора, и, наконец, вы EXEC этого динамического оператора:

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 '[email protected]+ 
     '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) 

ADVANCED

Иногда вы можете ожидать плохие данные, и вы можете защитить себя. Например, если это возможно для столового сорта, чтобы иметь спортивные идентификаторы, которые не в спортивной таблице можно изменить первый запрос, как следующий включить плохие данные в результатах:

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('') 
) 
+0

Код, который вы предоставили, работает на сервере MSSQL Server 2005 (но все еще есть ошибки), но когда я попробовал его на сервере 2000 (это версия, с которой я работаю), и это плохо. Там говорится, что есть что-то незаявленное. Но все же, это очень большая помощь для меня. Я пытаюсь изменить его и попытаться запустить его на SQL Server 2000. Спасибо, сэр! – eirishainjel

+0

@eirishainjel - необъявленное что? – Hogan

+0

@eirishainjel - У него нет ошибок в 2005 году с данными, которые вы дали. Может быть, вы не скопировали его правильно? – Hogan

0

В SQL Server 2000 (который не поддерживает оператор PIVOT) кросс-вкладки, основанные на сводных запросах, обычно строятся с использованием агрегатных функций, таких как MAX. Вот определение представления, которое создает необходимую структуру. Обратите внимание, что ваши спортивные столбцы должны быть полностью перечислены для всех возможных значений grade.sportid (для демонстрации добавлено значение «spo99»).

CREATE VIEW StudentSportsGrades 
AS 
SELECT s.idnumber, s.student, sp.teacher 
, MAX(CASE WHEN g.sportid=N'spo1' THEN g.grade END) AS [Soccer] 
, MAX(CASE WHEN g.sportid=N'spo17' THEN g.grade END) AS [Tennis] 
, MAX(CASE WHEN g.sportid=N'spo3' THEN g.grade END) AS [Chess] 
, MAX(CASE WHEN g.sportid=N'spo99' THEN g.grade END) AS [SomeOtherSport] 
FROM Student AS s 
INNER JOIN grade AS g ON g.idnumber=s.idnumber 
INNER JOIN sport AS sp ON sp.sportid=g.sportid 
GROUP BY s.idnumber, s.student, sp.teacher 
GO 

Вот запрос, который дает результаты, которые вам нужны.

SELECT idnumber, student, Soccer, Tennis, Chess 
FROM StudentSportsGrades 
WHERE teacher=91 
ORDER BY student 

Это статическая конструкция, поэтому она может быть такой же, как и другие примеры, которые вы видели в своем поиске. Но упаковка в виде дает некоторую возможность для получения результатов с различными столбцами и условиями фильтрации.

См. Также Crosstab Query in SQL Server 2000, который ссылается на способы использования динамического SQL для достижения этого.

+0

Я уже знаю и пробовал этот код, но я понял, что это не то, что мне нужно, потому что, как было сказано по моему вопросу, спорт динамически «создан». Значение, в зависимости от SY, спорт, возможно, изменится, и каждый студент будет заниматься различными видами спорта. Но все равно спасибо. :) – eirishainjel

0

Объявите колонны футбол, теннис и шахматы статические.

select s.idnumber,student, 
sum(case when sp.sportid='spo1' then grade end) as soccer 
,sum(case when sp.sportid='spo17' then grade end) as Tennis 
,sum(case when sp.sportid='spo3' then grade end) as Chess 
from student s 
inner join grade g on s.idnumber=g.idnumber 
inner join enrol e on e.sportid=g.sportid 
inner join sport sp on sp.sportid=e.sportid and sp.sy=e.sy 
where sp.teacher='91' 
group by s.idnumber,student 
+0

Я уже знал и пробовал этот код, но я понял, что это не то, что мне нужно, потому что, как указано на моем вопросе, спорт динамически «создается». Значение, в зависимости от SY, спорт, возможно, изменится, и каждый студент будет заниматься различными видами спорта. Но все равно спасибо. :) – eirishainjel