#sql #sql-server #crosstab
#sql #sql-server #перекрестная таблица
Вопрос:
У меня есть таблица в sql server, которая содержит три столбца: «дата», «полдень» и «3 часа дня». Первый столбец не требует пояснений, но последние два содержат имена приглашенных докладчиков в месте проведения в соответствии со временем их прибытия. Я хочу написать запрос с перекрестными вкладками, который записывает имена докладчиков в заголовок столбца и подсчитывает, сколько раз этот докладчик выступал в эту дату.
Пример
Date | Noon | 3pm
092916 | Tom | <null>
092816 | Dick | Tom
092716 | <null> | Suzy
Желаемый результат
Date | Dick | Tom | Suzy
092916 | <null> | 1 | <null>
092816 | 1 | 1 | <null>
092716 | <null> | <null> | 1
Я могу сделать это довольно легко с помощью запроса перекрестной таблицы, если я выбираю только один раз и помещаю количество в категорию значений, но у меня возникают проблемы с объединением несколько раз, чтобы я мог получить точное количество того, кто говорил в какой день.
Комментарии:
1. Слово, которое вы ищете, это
pivot
Ответ №1:
вы можете создавать свой запрос динамически.
это создаст оператор count (case) для каждого имени, найденного в столбце noon или 3pm.. аналогично COUNT(CASE WHEN 'Dick' IN ([Noon],[3pm]) THEN 1 END) as [Dick]
DECLARE @speakers NVARCHAR(MAX),
@sql NVARCHAR(MAX)
SET @speakers = STUFF((
SELECT ',COUNT(CASE WHEN ''' [Name] ''' IN ([Noon],[3pm]) THEN 1 END) as ' QUOTENAME([Name])
FROM (SELECT [Noon] AS [Name] FROM Table1
UNION ALL SELECT [3pm] FROM Table1) t
GROUP BY t.Name
FOR XML PATH('')
), 1, 1, '')
SET @sql = N'SELECT Date, ' @speakers ' FROM Table1 GROUP BY Date'
--Print @sql to see what's going on
EXEC(@sql)
Ответ №2:
Вы могли бы использовать этот запрос:
select *
from (
select date, noon as speaker, count(*) as times
from events
group by date, noon
union all
select date, [3pm], count(*)
from events
group by date, [3pm]
) as u
pivot (
sum(times)
for speaker in ([Dick], [Tom], [Suzy])
) as piv
order by date desc;
… который дает вам количество для каждой ячейки (null, 1 или 2):
Date | Dick | Tom | Suzy
092916 | <null> | 1 | <null>
092816 | 1 | 1 | <null>
092716 | <null> | <null> | 1
Комментарии:
1. Спасибо за ваш ответ. Мне действительно нужен подсчет, поскольку некоторые докладчики выступают дважды в один и тот же день. У меня также есть что-то вроде 50 динамиков за 5-летний период, некоторые из которых уникальны для своего временного интервала, что усложняет объединение, поскольку существуют разные столбцы, если вы поворачиваете каждый временной интервал по отдельности.
2. Хорошо, я обновил запрос для подсчета.
group by
Предложения необходимы, когда несколько записей могут иметь одну и ту же дату. Если в этом нет необходимости, вы можете при необходимости удалить их и заменитьcount(*)
на1
. Но если у вас неизвестное количество выступающих, я бы посоветовал вам использовать возможности вашей среды программирования. Это больше подходит для этого.