Превратить строки SQL в столбцы - PullRequest
0 голосов
/ 19 февраля 2019

Я импортировал много данных сборки из другой системы в MS SQL 2017, но столкнулся с проблемой превращения строк в столбцы.Большинство полей в системе импортируются из var-символов, и поле может иметь начальные / конечные пробелы.Поверьте мне, когда я говорю, я искал ответ во многих местах / страницах.

data:
key1   Unit       Measurement 
04A    Unit 1     156,8000
04A    Unit 2     5.845,3000
678R   Unit 1     8,6000
678R   Unit 2     409,6000
678R   Unit 3     17

how can data be turned into:
key1   Unit 1     Unit 2       Unit 3
04A    156,8000   5.845,3000   NULL
678R   8,6000     409,6000     17

столбец измерения - должен ли он быть плавающим или десятичным - мы здесь скандинавы :-)?

я пробовал pivot с max в качестве агрегатной функции, но в модуле 1, 2, 3 появляется слишком много строк с нулями - он даже отклоняет строки, имеющие значение

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Обязательно ограничьте набор столбцов сводной таблицы перед тем, как его применять:

;WITH PrePivot AS -- Limit the columns for the PIVOT's GROUP BY
(
    SELECT
        Key1,
        Unit,
        Measurement
    FROM
        YourTable
)
SELECT
    P.Key1,
    P.[Unit 1],
    P.[Unit 2],
    P.[Unit 3]
FROM
    PrePivot AS T
    PIVOT (
        MAX(T.Measurement) FOR T.Unit IN ([Unit 1], [Unit 2], [Unit 3])
    ) AS P

Пожалуйста, отметьте в этом посте , чтобы увидеть, как PIVOT на самом деле делает неявное GROUP BY со всеминеповоротные столбцы.

0 голосов
/ 19 февраля 2019

Вы можете попробовать это, используя PIVOT.Здесь вам нужно использовать MAX() функцию, а не AVG() или SUM(), поскольку сохраненные данные находятся в varchar.

create table #temp(key1 varchar(10), Unit Varchar(20), Measurement varchar(20))
insert into #temp values
('04A', 'Unit 1', '156,8000'),
('04A', 'Unit 2', '5.845,3000'),
('678R', 'Unit 1', '8,6000'),
('678R', 'Unit 2', '409,6000'),
('678R', 'Unit 3', '17')

SELECT * 
FROM 
(
    SELECT * FROM #temp
)AS FooData
PIVOT(
    MAX(FooData.Measurement)
    FOR Unit IN ([Unit 1], [Unit 2], [Unit 3])
) AS FooPivot

Вывод такой, как показано ниже:

key1    Unit 1      Unit 2      Unit 3
04A     156,8000    5.845,3000  NULL
678R    8,6000      409,6000    17
0 голосов
/ 19 февраля 2019

Вы можете использовать оператор PIVOT:

SELECT * 
FROM 
(
    SELECT * FROM YourTable
)AS FooData
PIVOT(
    AVG(FooData.Measurement)
    FOR Unit IN ([Unit 1], [Unit 2], [Unit 3])
) AS FooPivot

Пример:

DECLARE @tbl TABLE
(
   key1   varchar(50),
   Unit   VARCHAR(50),
   Measurement DECIMAL(18,8)
)

INSERT INTO @tbl
(
    key1,
    Unit,
    Measurement
)
VALUES
  ('04A', 'Unit 1',     156.8000)
, ('04A', 'Unit 2',     5.8453000)
, ('678R', 'Unit 1',     8.6000)
, ('678R', 'Unit 2',     409.6000)
, ('678R', 'Unit 3',     17)
SELECT * 
FROM 
(
    SELECT * FROM @tbl
)AS FooData
PIVOT(
    AVG(FooData.Measurement)
    FOR Unit IN ([Unit 1], [Unit 2], [Unit 3])
) AS FooPivot

ВЫХОД:

key1    Unit 1            Unit 2        Unit 3
04A     156.80000000    5.84530000      NULL
678R    8.60000000      409.60000000    17.00000000

ОБНОВЛЕНИЕ:

Я не знаю, какой фактический тип данных поля Measurement имеет значение 5.845,3000, однако я твердо верю, что эти данные имеют тип numeric.Если да, то лучше хранить числовые данные как числовой тип, так как это ответственность уровня представления, потому что существуют разные требования для отображения чисел в разных странах.Для добавления запятых вы можете использовать каналы на стороне клиента.

Кроме того, если Measurement является типом номера и вы сохраните его как varchar(50), то при оформлении заказа у вас возникнут проблемы.Так что лучше хранить как numeric.

В противном случае вы можете использовать тип данных varchar(255):

DECLARE @tbl TABLE
(
   key1   varchar(50),
   Unit   VARCHAR(50),
   Measurement VARCHAR(255)
)

INSERT INTO @tbl
(
    key1,
    Unit,
    Measurement
)
VALUES
  ('04A', 'Unit 1',     '156.8000')
, ('04A', 'Unit 2',     '5,845.3000')
, ('678R', 'Unit 1',     '8.6000')
, ('678R', 'Unit 2',     '409.6000')
, ('678R', 'Unit 3',     '17')
SELECT * 
FROM 
(
    SELECT * FROM @tbl
)AS FooData
PIVOT(
    MAX(FooData.Measurement)
    FOR Unit IN ([Unit 1], [Unit 2], [Unit 3])
) AS FooPivot
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...