У меня есть набор данных, который организован следующим образом:
Timestamp|A0001|A0002|A0003|A0004|B0001|B0002|B0003|B0004 ...
---------+-----+-----+-----+-----+-----+-----+-----+-----
2008-1-1 | 1 | 2 | 10 | 6 | 20 | 35 | 300 | 8
2008-1-2 | 5 | 2 | 9 | 3 | 50 | 38 | 290 | 2
2008-1-4 | 7 | 7 | 11 | 0 | 30 | 87 | 350 | 0
2008-1-5 | 1 | 9 | 1 | 0 | 25 | 100 | 10 | 0
...
Где A0001 — это значение A элемента № 1, а B0001 — значение B элемента № 1. В таблице может быть более 60 различных элементов, и каждый элемент имеет столбец значений A и столбец значений B, то есть всего в таблице более 120 столбцов.
Я хочу получить результат из 3 столбцов (индекс элемента, значение A, значение B), который суммирует значения A и B для каждого элемента:
Index | A Value | B Value
------+---------+--------
0001 | 14 | 125
0002 | 20 | 260
0003 | 31 | 950
0004 | 9 | 10
....
Когда я перехожу от столбцов к строкам, я ожидаю поворота в решении, но я не уверен, как это конкретизировать. Часть проблемы заключается в том, как убрать A и B, чтобы сформировать значения для столбца Index. Другая часть заключается в том, что мне никогда раньше не приходилось использовать Pivot, поэтому я также спотыкаюсь о базовый синтаксис.
Я думаю, что в конечном итоге мне нужно иметь многошаговое решение, которое сначала строит суммирование как:
ColName | Value
--------+------
A0001 | 14
A0002 | 20
A0003 | 31
A0004 | 9
B0001 | 125
B0002 | 260
B0003 | 950
B0004 | 10
Затем измените данные ColName, чтобы удалить индекс:
ColName | Value | Index | Aspect
--------+-------+-------+-------
A0001 | 14 | 0001 | A
A0002 | 20 | 0002 | A
A0003 | 31 | 0003 | A
A0004 | 9 | 0004 | A
B0001 | 125 | 0001 | B
B0002 | 260 | 0002 | B
B0003 | 950 | 0003 | B
B0004 | 10 | 0004 | B
Наконец, самообъединение, чтобы переместить значения B рядом со значениями A.
Кажется, это долгий процесс, чтобы получить то, что я хочу. Поэтому мне нужен совет относительно того, иду ли я по правильному пути, или есть другой подход, который я упустил из виду, который сделает мою жизнь намного проще.
Примечание 1) Решение должно быть в T-SQL на MSSQL 2005.
Примечание 2) Формат таблицы изменить нельзя.
Редактировать Другой метод, о котором я думал, использует UNION и отдельные SUM() для каждого столбца:
SELECT '0001' as Index, SUM(A0001) as A, SUM(B0001) as B FROM TABLE
UNION
SELECT '0002' as Index, SUM(A0002) as A, SUM(B0002) as B FROM TABLE
UNION
SELECT '0003' as Index, SUM(A0003) as A, SUM(B0003) as B FROM TABLE
UNION
SELECT '0004' as Index, SUM(A0004) as A, SUM(B0004) as B FROM TABLE
UNION
...
Но и этот подход выглядит не очень красиво
EDIT На данный момент есть 2 отличных ответа. Но я хотел бы добавить в запрос еще два условия :-)
1) Мне нужно выбрать строки на основе диапазона временных меток (minv ‹ timestamp ‹ maxv).
2) Мне также нужно условно выбрать строки в UDF, который обрабатывает метку времени
Используя имена таблиц Бретски, приведенное выше переводится как:
...
(SELECT A0001, A0002, A0003, B0001, B0002, B0003
FROM ptest
WHERE timestamp>minv AND timestamp<maxv AND fn(timestamp)=fnv) p
unpivot
(val for item in (A0001, A0002, A0003, B0001, B0002, B0003)) as unpvt
...
Учитывая, что я условно добавил требование fn(), я думаю, что мне также нужно пойти по пути динамического SQL, предложенному Джонатаном. Тем более, что мне нужно построить один и тот же запрос для 12 разных таблиц - все в одном стиле.