#sql-server #unpivot
#sql-server #неисправный
Вопрос:
У меня есть файл импорта CSV, который я не могу контролировать в отношении имен или формата столбцов. Заголовки состоят из id,[temperature range 1],[temperature range 2],[temperature range 3],[temperature range],[temperature range 5],[temperature range 6],[temperature range 7],[temperature range 8], [temperature range 9],[temperature range 10],[temperature range 11],[temperature range 12], [Pressure Range 1],[Pressure Range 2],[Pressure Range 3],[Pressure Range 4],[Pressure Range 5], [Pressure Range 6],[Pressure Range 7],[Pressure Range 8],[Pressure Range 9], [Pressure Range 10],[Pressure Range 11],[Pressure Range 12],[Calcite Saturation 1],[Calcite Saturation 2],[Calcite Saturation 3],[Calcite Saturation 4],[Calcite Saturation 5],[Calcite Saturation 6],[Calcite Saturation 7],[Calcite Saturation 8],[Calcite Saturation 9],[Calcite Saturation 10],[Calcite Saturation 11],[Calcite Saturation 12]
.
Я смог отключить таблицу, используя этот код:
Select id,Temp,Psia,CalciteX
from (
Select id,[temperature range 1],[temperature range 2],[temperature range 3],[temperature range 4],[temperature range 5],[temperature range 6],[temperature range 7],[temperature range 8], [temperature range 9],[temperature range 10],[temperature range 11],[temperature range 12],[Pressure Range 1],[Pressure Range 2],[Pressure Range 3],[Pressure Range 4],[Pressure Range 5], [Pressure Range 6],[Pressure Range 7],[Pressure Range 8],[Pressure Range 9],[Pressure Range 10],[Pressure Range 11],[Pressure Range 12],[Calcite Saturation 1],[Calcite Saturation 2], [Calcite Saturation 3],[Calcite Saturation 4],[Calcite Saturation 5],[Calcite Saturation 6],[Calcite Saturation 7],[Calcite Saturation 8],[Calcite Saturation 9],[Calcite Saturation 10], [Calcite Saturation 11],[Calcite Saturation 12]
from frenchcreekscale where id ='10009-2019111114.1/P' ) as src
UNPivot ( Temp for Temps in([temperature range 1],[temperature range 2],[temperature range 3],[temperature range 4],[temperature range 5],[temperature range 6],[temperature range 7],[temperature range 8], [temperature range 9],[temperature range 10],[temperature range 11],[temperature range 12]) ) AS Temps
UNPivot ( Psia for Pressures in([Pressure Range 1],[Pressure Range 2],[Pressure Range 3],[Pressure Range 4],[Pressure Range 5],[Pressure Range 6],[Pressure Range 7],[Pressure Range 8],[Pressure Range 9], [Pressure Range 10],[Pressure Range 11],[Pressure Range 12]) ) AS Pressures
UNPivot ( CalciteX for CalciteXs in([Calcite Saturation 1],[Calcite Saturation 2], [Calcite Saturation 3],[Calcite Saturation 4],[Calcite Saturation 5],[Calcite Saturation 6],[Calcite Saturation 7],[Calcite Saturation 8],[Calcite Saturation 9],[Calcite Saturation 10], [Calcite Saturation 11],[Calcite Saturation 12]) ) AS CalX
Это частичный вывод, который я получаю:
id Temp Psia CalciteX
-------------------- ---- ---- --------
10009-2019111114.1/P 70 0 0.165885
10009-2019111114.1/P 70 0 0.180097
10009-2019111114.1/P 70 0 0.195601
10009-2019111114.1/P 70 0 0.211319
10009-2019111114.1/P 70 0 0.226902
10009-2019111114.1/P 70 0 0.241826
10009-2019111114.1/P 70 0 0.25538
10009-2019111114.1/P 70 0 0.267159
10009-2019111114.1/P 70 0 0.276571
10009-2019111114.1/P 70 0 0.283237
10009-2019111114.1/P 70 0 0.286532
10009-2019111114.1/P 70 0 0.286462
10009-2019111114.1/P 70 147 0.165885
10009-2019111114.1/P 70 147 0.180097
10009-2019111114.1/P 70 147 0.195601
10009-2019111114.1/P 70 147 0.211319
10009-2019111114.1/P 70 147 0.226902
10009-2019111114.1/P 70 147 0.241826
10009-2019111114.1/P 70 147 0.25538
10009-2019111114.1/P 70 147 0.267159
10009-2019111114.1/P 70 147 0.276571
10009-2019111114.1/P 70 147 0.283237
10009-2019111114.1/P 70 147 0.286532
10009-2019111114.1/P 70 147 0.286462
10009-2019111114.1/P 70 278 0.165885
10009-2019111114.1/P 70 278 0.180097
etc
Должно быть только 12 записей:
id Temp
-------------------- ----
10009-2019111114.1/P 70
10009-2019111114.1/P 80
10009-2019111114.1/P 90
10009-2019111114.1/P 100
10009-2019111114.1/P 110
10009-2019111114.1/P 120
10009-2019111114.1/P 130
10009-2019111114.1/P 140
10009-2019111114.1/P 150
10009-2019111114.1/P 160
10009-2019111114.1/P 170
10009-2019111114.1/P 180
С другими полями, привязанными к идентификатору.
Я не понимаю, как отключить следующий столбец без создания нескольких записей.
Ответ №1:
pivot
и unpivot
работают лучше всего, когда вы предоставляете им только столбцы, необходимые для сводки. Ваше src
подмножество содержит столбцы для 3 unpivot
-х. Если вы разделите их на отдельные общие табличные выражения (CTE), вы можете затем объединить их обратно в id
столбце.
Пожалуйста, обратите внимание, что одного id
присоединения будет недостаточно. Это все равно даст вам несколько строк. Вы хотите, чтобы значение для [temperature range 1]
находилось в той же строке, что и [Pressure Range 1]
и [Pressure Range 1]
. Поэтому вы должны добавить это в свои критерии объединения.
В моем упрощенном примере я использовал единственный крайний правый символ из имени столбца для построения этого дополнительного критерия объединения (давая мне 1
и 2
). Ваше полное решение должно содержать последние два числа из имен столбцов (что дает вам 1
to 12
).
Упрощенный образец данных
create table MyTable
(
id int,
A1 nvarchar(4),
A2 nvarchar(4),
B1 nvarchar(4),
B2 nvarchar(4)
);
insert into MyTable (id, A1, A2, B1, B2) values
(1, '1A11', '1A21', '1B11', '1B21'),
(2, '2A11', '2A21', '2B11', '2B12');
Упрощенное решение
with cte_A as
(
select upA.id, upA.AValue, upA.AType
from (select id, A1, A2 from MyTable) a
unpivot (AValue for AType in ([A1], [A2])) upA
),
cte_B as
(
select upB.id, upB.BValue, upB.BType
from (select id, B1, B2 from MyTable) b
unpivot (BValue for BType in ([B1], [B2])) upB
)
select ca.id, right(ca.AType, 1) as Num, ca.AValue, ca.AType, cb.BValue, cb.BType
from cte_A ca
join cte_B cb
on cb.id = ca.id -- match on id
and right(cb.BType, 1) = right(ca.AType, 1); -- match on type (bring A1 and B1 to same line)
Пример вывода
id Num AValue AType BValue BType
-- --- ------ ----- ------ -----
1 1 1A11 A1 1B11 B1
1 2 1A21 A2 1B21 B2
2 1 2A11 A1 2B11 B1
2 2 2A21 A2 2B12 B2
Существующий запрос
Оглядываясь назад на мое решение: вы также можете применить «дополнительный критерий объединения» к вашему существующему запросу. Добавьте что-то вроде следующего:
...
where right(CalX.Temps, 2) = right(CalX.Pressures, 2)
and right(CalX.Temps, 2) = right(CalX.CalciteXs, 2);
Скрипта, которая применяет это решение к упрощенной версии вашего запроса.