2016-02-01 2 views
2

У меня есть таблица для событий календаря с следующей схемой:Использование Pivot на более чем одного столбца в SQL Server

CREATE TABLE [dbo].[Calendar](
    [ID] [int] NOT NULL, 
    [PersonCode] [int] NOT NULL, 
    [Title] [nvarchar](50) NULL, 
    [Description] [nvarchar](max) NULL, 
    [StartDate] [datetime] NULL, 
    [EndDate] [datetime] NULL, 
    [NotifyOrder] [int] NULL) 

INSERT INTO [dbo].[Calendar] 
     ([ID] 
     ,[PersonCode] 
     ,[Title] 
     ,[Description] 
     ,[StartDate] 
     ,[EndDate] 
     ,[NotifyOrder]) 
VALUES 
     (1 
     ,1000 
     ,'Calendar Event 1' 
     ,'Description For Event 1' 
     ,'2016/01/28 08:00' 
     ,'2016/01/28 09:00' 
     ,1) 


INSERT INTO [dbo].[Calendar] 
     ([ID] 
     ,[PersonCode] 
     ,[Title] 
     ,[Description] 
     ,[StartDate] 
     ,[EndDate] 
     ,[NotifyOrder])  
VALUES 
     (2 
     ,1000 
     ,'Calendar Event 2' 
     ,'Description For Event 2' 
     ,'2016/01/28 09:00' 
     ,'2016/01/28 10:00' 
     ,2) 

INSERT INTO [dbo].[Calendar] 
     ([ID] 
     ,[PersonCode] 
     ,[Title] 
     ,[Description] 
     ,[StartDate] 
     ,[EndDate] 
     ,[NotifyOrder])  
VALUES 
     (3 
     ,1000 
     ,'Calendar Event 3' 
     ,'Description For Event 3' 
     ,'2016/01/28 10:00' 
     ,'2016/01/28 11:00' 
     ,3) 

Мне нужно отобразить строки в формате, как это:

EventDate | 1  | Title1   |  2  | Title2   |  3  | Title3   | 
----------------------------------------------------------------------------------------------------------- 
    2016-01-28|08:00-09:00 | Calendar Event 1 |09:00-10:00| Calendar Event 2 |10:00-11:00| Calendar Event 3 | 

Когда Я использую стержень только на строке столбца чисел (Здесь NotifyOrder), то outpu правильно (без заголовка столбцов):

SELECT EventDate 
, [1], [2], [3], [4], [5], [6] 
FROM 
(
SELECT NotifyOrder 
    ,CAST(StartDate AS Date) EventDate 
    ,FORMAT(StartDate ,'hh:mm') + ' - ' + FORMAT(EndDate ,'hh:mm') EventTime 
FROM [Calendar] 
) Notifies 

PIVOT 
(
    Max(EventTime) for NotifyOrder IN([1], [2], [3], [4], [5], [6]) 
) AS PV1 

Результат:

EventDate  1   | 2    | 3    | 4 | 5  | 6 
----------------------------------------------------------------------------------------------- 
2016-01-28 08:00 - 09:00 | 09:00 - 10:00 | 10:00 - 11:00 | NULL | NULL | NULL 

Но когда я добавляю Pivot на названии столбцов, результат отображается в нескольких строках:

SELECT EventDate 
     , [1], [2], [3], [4], [5], [6] 
     , [Title1], [Title2], [Title3], [Title4], [Title5], [Title6] 
    FROM 
    (
    SELECT NotifyOrder 
      ,CAST(StartDate AS Date) EventDate 
    ,FORMAT(StartDate ,'hh:mm') + ' - ' + FORMAT(EndDate ,'hh:mm') EventTime    ,Title, 'Title' + CAST(NotifyOrder AS Varchar(2)) AS EventTitle 
    FROM [Calendar] 
    ) Notifies 

    PIVOT 
    (
     Max(EventTime) for NotifyOrder IN([1], [2], [3], [4], [5], [6]) 
    ) AS PV1 

    PIVOT 
    (
     MAX (Title) for EventTitle IN([Title1], [Title2], [Title3], [Title4], [Title5], [Title6]) 
    ) AS PV2 

EventDate 1 2 3 4 5 6 Title1 Title2 Title3 Title4 Title5 Title6 
2016-01-28 (null) (null) 10:00 - 11:00 (null) (null) (null) (null) (null) Calendar Event 3 (null) (null) (null) 
2016-01-28 (null) 09:00 - 10:00 (null) (null) (null) (null) (null) Calendar Event 2 (null) (null) (null) (null) 
2016-01-28 08:00 - 09:00 (null) (null) (null) (null) (null) Calendar Event 1 (null) (null) (null) (null) (null) 

Вот SQL Скрипки источник:

http://sqlfiddle.com/#!6/a34a5/1

ответ

3

Использование условной агрегации и FORMAT:

SELECT PersonCode 
,[1]  = MAX(CASE WHEN rn = 1 THEN EventTime END) 
,[Title1] = MAX(CASE WHEN rn = 1 THEN Title END) 
,[2]  = MAX(CASE WHEN rn = 2 THEN EventTime END) 
,[Title2] = MAX(CASE WHEN rn = 2 THEN Title END) 
,[3]  = MAX(CASE WHEN rn = 3 THEN EventTime END) 
,[Title3] = MAX(CASE WHEN rn = 3 THEN Title END) 
FROM (SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY PersonCode ORDER BY id) 
      ,EventTime = FORMAT(StartDate, 'hh:mm') + '-' + FORMAT(EndDate, 'hh:mm') 
     FROM #Calendar) AS sub 
GROUP BY PersonCode; 

LiveDemo

Выход:

╔════════════╦═════════════╦══════════════════╦═════════════╦══════════════════╦═════════════╦══════════════════╗ 
║ PersonCode ║  1  ║  Title1  ║  2  ║  Title2  ║  3  ║  Title3  ║ 
╠════════════╬═════════════╬══════════════════╬═════════════╬══════════════════╬═════════════╬══════════════════╣ 
║  1000 ║ 08:00-09:00 ║ Calendar Event 1 ║ 09:00-10:00 ║ Calendar Event 2 ║ 10:00-11:00 ║ Calendar Event 3 ║ 
╚════════════╩═════════════╩══════════════════╩═════════════╩══════════════════╩═════════════╩══════════════════╝ 

Если вы используете SQL Server ниже, чем 2012, изменить FORMAT к пользовательскому коду.

+0

Для простого преобразования во времени в качестве строки я бы лично придерживался того, что имеет OP. Для нескольких строк это может быть не очень много, но ['FORMAT' может быть дорогим] (http://sqlperformance.com/2015/06/t-sql-queries/format-is-nice-and-all- но), поэтому, вероятно, лучше всего избегать, где это возможно. – GarethD

+0

Я пробовал много способов решить эту проблему с помощью Pivot. Но я думаю, что это невозможно. Спасибо за Ваш ответ. – Mostapha777

Смежные вопросы