неисправленная проблема с несколькими аналогичными столбцами

#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);
  

Скрипта, которая применяет это решение к упрощенной версии вашего запроса.