SQL Server 2008 анализирует неизвестное количество записей

#sql #tsql #sql-server-2008

#sql #tsql #sql-server-2008

Вопрос:

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

У меня есть таблица, подобная этой:

 ID    NAME     CLASS
----------------------
1     BOB      Course1
1     BOB      Course2
1     BOB      Course3
2     JOHN     Course1
2     JOHN     Course2
3     SAM      Course1
4     BILL     Course2
4     BILL     Course3
  

Я хочу, чтобы это выглядело так, где последний столбец предназначен для того, у кого больше всего классов:

 ID    NAME     CLASS     CLASS2     CLASS3     CLASS4..........
------------------------------------------------------
1     BOB      Course1   Course2    Course3    NULL............
2     JOHN     Course1   Course2    NULL       NULL............
3     SAM      Course1   NULL       NULL       NULL............
4     BILL     Course2   Couse3     NULL       NULL............
  

Лучшая идея, которая у меня была, заключалась в том, чтобы продолжать получать КЛАСС max и удалять его, пока у меня не закончатся записи.

редактировать: Для уточнения: заголовки моих столбцов не будут фактическими курсами, а просто способом указать, на сколько курсов назначен преподаватель.

Ответ №1:

Предложение Эйба выглядит следующим образом:

  select * from Class
 pivot (COUNT(ID) for CLASS in ([Course1],[Course2],[Course3])) as Taking
  

Что дает такие результаты:

 Name    Course1 Course2 Course3
BILL    0       1       1
BOB     1       1       0       
JOHN    1       1       0
SAM     1       0       0       
  

Конечно, это немного отличается от того, что вы хотите… вы хотите, чтобы курс 1 имел значение для «первого курса». Единственный способ сделать это — использовать динамический SQL.

Если вам нужен разделенный запятыми список курсов (в одном столбце), который намного проще и быстрее генерировать.


Список с запятыми

 select c.Name, 
       STUFF((SELECT ( ', '   c2.Class )
               FROM #Class c2
               WHERE c.Name = c2.Name
               ORDER BY c2.Class 
               FOR XML PATH( '' )),1,2,'') as [Class List]
FROM #Class c 
GROUP BY c.Name 
  

Дает вам:

 Name   Class List
BILL   Course2, Course3
BOB    Course1, Course2, Course3
JOHN   Course1, Course2
SAM    Course1
  

Комментарии:

1. Да, если бы у меня было небольшое количество курсов, и я знал названия, которые бы хорошо работали, но у меня есть несколько тысяч разных курсов, и названия могут меняться изо дня в день.

2. Я полагаю, я мог бы взять это, а затем переформатировать его в отдельные поля с нумерацией столбцов yes.

Ответ №2:

Вы можете посмотреть на использование СВОДНОЙ

Подробнее об этом читайте здесь:

http://msdn.microsoft.com/en-us/library/ms177410.aspx

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

Комментарии:

1. Я прочитал эту ссылку, и кажется, что все значения of известны. Я мог бы выполнить подсчет отдельных курсов по идентификатору, чтобы получить # столбцов, но я никогда не узнаю названия курсов.

2. Это усложняет задачу. Вы можете посмотреть на использование динамического SQL для этого, но я не уверен, что это ваш лучший вариант. Позвольте мне посмотреть, смогу ли я найти лучшее решение.

3. Динамическое количество столбцов: simple-talk.com/community/blogs/andras/archive/2007/09/14 /…