Как выбрать набор данных SQL, в котором значения в первой строке являются именами столбцов? - PullRequest
0 голосов
/ 09 июля 2020

У меня есть данные, которые выглядят так:

ID RowType Col_1       Col_2     Col_3       ... Col_n
1  HDR     FirstName   LastName  Birthdate
2  DTL     Steve       Bramblet  1989-01-01
3  DTL     Bob         Marley    1967-03-12
4  DTL     Mickey      Mouse     1921-04-25

И я хочу вернуть таблицу или набор данных, которые выглядят следующим образом:

ID    FirstName    LastName    Birthdate
2     Steve        Bramblet    1989-01-01
3     Bob          Marley      1967-03-12
4     Mickey       Mouse       1921-04-25

, где n = 255 (так что ограничение в 255 полей Col_)

*** EDIT: данные в строке HDR являются произвольными, поэтому я просто использую FirstName, LastName, Birthdate в качестве примеров. Вот почему я подумал, что это должно быть Dynami c SQL, поскольку имена столбцов, которые я хочу получить, будут меняться в зависимости от значений в строке HDR. СПАСИБО! ***

Если есть чисто SQL решение, это то, что мне нужно. Он переходит в процесс ETL (SSIS), поэтому я мог бы использовать задачу «Сценарий», если все остальное не помогло.

Даже если бы я мог вернуть одну строку, это было бы решением. Я думал, что может быть решение Dynami c sql для чего-то вроде этого:

select Col_1 as FirstName, Col_2 as LastName, Col_3 as Birthdate

Ответы [ 4 ]

0 голосов
/ 09 июля 2020

Ну ладно. Существует чистый подход SSIS, предполагающий, что источником является таблица SQL. Вот это довольно схематично.

  1. Создайте переменную oColSet с типом Object и 255 переменных типа String и именами sColName_1, sColName_2 .. . sColName_255.

  2. Создайте задачу SQL с запросом типа select top(1) Col_1, Col_2, ... Col_255 from Src where RowType = 'HDR', установите свойства задачи ResultSet = Полный набор результатов , на вкладке набора результатов - установите Имя результата до 0 и Имя переменной до oColSet.

  3. Добавить перечислитель ForEach L oop, установить его как ForEach ADO Enumerator, Исходная переменная объекта ADO - устанавливается в oColSet, Режим перечисления = Строки в первой таблице . Затем на вкладке Сопоставления переменных укажите в качестве примера (Variable - Index) - sColName_1 - 0, sColName_2 - 1, ... sColName_255 - 254.

  4. Создайте переменную sSQLQuery с типом String и Variable Expression like

    "SELECT Col_1 AS ["+@[User::sColName_1]+"], 
        Col_2 AS ["+@[User::sColName_2]+"], 
        ...
        Col_255 AS ["+@[User::sColName_255]+"]
     FROM Src WHERE RowType='DTL'" 
    
  5. В ForEach L oop - добавьте свой поток данных в OLEDB Источник - установите Режим доступа к данным на SQL команду из переменной и укажите имя переменной User::sSQLQuery. В самом потоке данных - установите DelayValidation = true .

Основная идея этого дизайна - получить все имена столбцов и сохранить их во временной переменной (шаг 2) . Затем шаг 3 выполняет синтаксический анализ и помещает все результаты в соответствующие переменные, 1 столбец (0-й) - в sColName_1 et c. Шаг 4 определяет команду SQL как выражение, которое вычисляется каждый раз при чтении переменной. Наконец, в ForEach L oop (где выполняется синтаксический анализ) вы выполняете свой поток данных.

Ограничения SSIS - типы данных и имена столбцов должны быть такими же во время выполнения, что и во время разработки. Если вам нужно сохранить свой набор данных в SQL - дайте мне знать, и я смогу скорректировать предложенное решение.

0 голосов
/ 09 июля 2020

Не уверен, что ваш первый фрагмент данных уже находится в таблице oracle или нет, но он находится в файле CSV, тогда у вас есть возможность во время загрузки пропускать заголовки.

Если данные уже есть в таблице, то вы можете использовать UNION, чтобы получить желаемый результат

Select * from table name where rowtype=‘HRD’
union
select * from table name where rowtype=‘DTL’

Если вам нужно Имя и c в качестве заголовка столбца, вам не нужно ничего делать. Создайте столбцы таблицы назначения в соответствии с вашими требованиями.

0 голосов
/ 09 июля 2020

Попробуйте следующее, используя row_number. Вот демонстрация .

with cte as
(
  select
    *,
    row_number() over (order by id) as rn
  from myTable
)

select
    ID,
    Col_1 as FirstName,
    Col_2 as LastName,
    Col_3 as Birthdate
from cte
where rn > 1

вывод:

| id  | firstname | lastname | birthdate  |
| --- | --------- | -------- | ---------- |
| 2   | Steve     | Bramblet | 1989-01-01 |
| 3   | Bob       | Marley   | 1967-03-12 |
| 4   | Mickey    | Mouse    | 1921-04-25 |
0 голосов
/ 09 июля 2020

Извините, отправил ответ, но я совершенно неправильно понял, что у вас были желаемые заголовки столбцов как data в исходной таблице.

Одно тривиальное решение (хотя оно требует большего количества операций ввода-вывода) было бы чтобы выгрузить данные таблицы в плоский файл без заголовков, затем прочитать его обратно, но на этот раз сообщить SSIS, что первая строка имеет заголовки, и игнорировать столбец RowType. Убедитесь, что вы правильно отсортировали данные, прежде чем записывать их в промежуточный файл!

Чтобы сделать дамп в файл без заголовков, вы должны установить ColumnNamesInFirstDataRow на false. Установите это в окне свойств, а не редактируя соединение. Дополнительная информация в этой ветке

Если у вас много данных, это, очевидно, очень неэффективно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...