2017-01-04 3 views
1

Я знаю, что есть много ответов, но ни один из моих применений. Моя таблица выгляделаSQL Транспонирование строк в столбцы без агрегата

enter image description here

, где мы храним метр и выключаться состояния на данный момент времени. После каждого состояния выключения появляется состояние «Вкл.». Мы хотим, чтобы перенести таблицу как этот

MeterNo |  [power off]  |   [power on] 
____________________________________________________________________ 
    x0039938 | 2016-10-08 14:14:37.610 | 2016-10-08 14:17:15.047 
____________________________________________________________________ 
    x0039938 | 2016-10-08 14:20:50.257 | NULL 
____________________________________________________________________ 
    x0039938 | 2016-10-08 14:23:07.610 | 2016-10-08 14:23:17.920 
____________________________________________________________________ 
    x0039940 | 2016-10-08 15:45:38.250 | 2016-10-08 15:52:40.080 
____________________________________________________________________ 

и так далее

Я попробовал этот запрос

SELECT * 
    FROM 
(
    SELECT MeterNo, Status, CreatedOn 
    FROM [BreakdownShutdowDetails] 
) s 
PIVOT 
(
    MAX(CreatedOn) FOR Status IN ([power off], [power on]) 
) p 

, который дает только на результат в meterno как этот

enter image description here

Основная идея, чтобы получить время между статусом Off on On каждый измерительный прибор. Пожалуйста, предложите для правильного запроса. Спасибо.

Update 1 Выборочные данные

1 x0039938 power off 2016-10-08 14:14:37.610 
2 x0039938 power on 2016-10-08 14:17:15.047 
3 x0039938 power off 2016-10-08 14:20:50.257 
4 x0039938 power off 2016-10-08 14:23:07.610 
5 x0039938 power on 2016-10-08 14:23:17.920 
6 x0039940 power off 2016-10-08 15:45:38.250 
7 x0039940 power on 2016-10-08 15:52:40.080 
8 x0040281 power off 2016-10-08 15:59:26.513 
9 x0040281 power on 2016-10-08 16:20:23.323 
10 x0039940 power off 2016-10-08 16:26:29.133 
19 x0040281 power off 2016-10-08 17:17:48.900 
22 x0039937 power off 2016-10-08 17:24:24.617 
23 x0039937 power on 2016-10-08 17:24:38.590 
24 x0039937 power off 2016-10-08 17:33:31.843 
25 x0039937 power on 2016-10-08 17:35:47.470 
27 x0039940 power off 2016-10-08 17:37:18.360 
28 x0040281 power on 2016-10-08 17:40:08.093 
30 x0043637 power off 2016-10-09 14:32:23.130 
31 x0039937 power off 2016-10-09 14:32:24.893 
32 x0040281 power off 2016-10-09 14:32:27.387 
33 x0039940 power off 2016-10-09 14:32:29.407 
34 x0040281 power on 2016-10-09 15:01:42.480 
+0

Это похоже на проблему с пробелами и островами. –

+0

Какова версия sql-сервера? – Viki888

+0

@ Viki888 SQL Server 2008 –

ответ

1

Это называется обычно называют Gaps and islands проблемой. Попробуйте что-нибудь подобное (Не проверено)

SELECT MeterNo, 
     [power off] = Min(CASE 
          WHEN status = 'power off' THEN CreatedOn 
         END), 
     [power on] = Min(CASE 
          WHEN status = 'power on' THEN CreatedOn 
         END) 
FROM (SELECT *, 
       Row_number() OVER (partition BY MeterNo ORDER BY CreatedOn) - 
       Dense_rank() OVER (partition BY MeterNo ORDER BY status) AS seq_grp 
     FROM Yourtable) t 
GROUP BY MeterNo, 
      seq_grp 
+0

предоставленные данные образца –

+0

@ صفي - Вы его протестировали? –

+0

Спасибо, он работает хорошо. –