SQL - конвертировать / транспонировать строки с кодированными текстовыми значениями в столбцы - PullRequest
0 голосов
/ 10 мая 2018

Мне нужна помощь для преобразования таблицы с данными, хранящимися в строках, в данные, хранящиеся в таблицах.

Справочная информация ... Я работаю с таблицей, содержащей данные о госпитализации. Назовем таблицу «Стационарные».

Данные в настоящее время отформатированы как таблица с 3 столбцами и n строками. 3 столбца содержат следующие данные:

"Patient_ID" = уникальный идентификатор пациента / человека . Думайте об этом как имя пациента; "Event_ID" = уникальный идентификатор события допуска . Выявляет уникальные эпизоды оказания медицинской помощи в стационаре; «Код диагноза» = Код ICD-10 , используемый для записи причины, по которой пациент находится в больнице.

Для отдельного пациента (Patient_ID) каждое пребывание в больнице (Event_ID) представлено одной или несколькими строками в таблице, где одна строка используется для каждого диагноза, который регистрируется для данного пребывания в больнице.

Таким образом, любое данное пребывание в больнице может быть зафиксировано одной строкой в ​​таблице (один зарегистрированный диагноз) или несколькими строками в таблице (связано с несколькими диагнозами).

Пример текущей таблицы "Стационарные" приведен ниже ...

-------------------------------------------
Patient_ID |  Event_ID   |  Diagnosis_Code
-------------------------------------------
Pers001    | HospStay001 |     C139
Pers001    | HospStay001 |     I245
Pers001    | HospStay001 |     D456
Pers001    | HospStay002 |     C139
Pers001    | HospStay002 |     J123
Pers555    | HospStay001 |     D312
Pers999    | HospStay001 |     C120
Pers999    | HospStay001 |     E101

Вот что я действительно хочу сделать : я хочу преобразовать данные так, чтобы у меня было только одна строка для каждого пребывания в стационаре на пациента , так что приведенная выше таблица отформатирован следующим образом:

----------------------------------------------------------------------------------------------------
Patient_ID |  Event_ID   | Diagnosis_Code_1 | Diagnosis_Code_2 | Diagnosis_Code_3 | Diagnosis_Code_n
----------------------------------------------------------------------------------------------------
Pers001    | HospStay001 |       C139       |       I245       |       D456       |
Pers001    | HospStay002 |       C139       |       J123       |                  |
Pers555    | HospStay001 |       D312       |                  |                  |
Pers999    | HospStay001 |       C120       |       E101       |                  |

Я подозреваю, что решение требует некоторого динамического SQL ... Боюсь, это не одно из моих преимуществ.

Спасибо!

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

Раджат верен - вам нужен какой-то столбец, чтобы использовать для создания Diagnosticcolumn_1, dignosis_column_2 .... и т.д.Столбцы диагностики 2. Используйте VBA для заполнения (быстрее для больших баз данных) следующим образом:

Sub Update_Diagnosis_Code_ID()

Dim db As DAO.Database
'Dim qdf As DAO.QueryDef
Dim rs As DAO.Recordset

Dim TmpRecord As String

Dim dummyId As Integer
Dim patientID As String
Dim eventID As String

Dim lastDummyId As Integer
Dim lastpatientID As String
Dim lasteventID As String

Dim i As Integer

pstrSQL = "SELECT Inpat.Dummy_id, Inpat.Patient_id, Inpat.Event_ID, Inpat.Diagnosis_Code FROM Inpat ORDER BY Inpat.Patient_id, Inpat.Event_ID;"
Set db = CurrentDb

Set rs = db.OpenRecordset(pstrSQL)

dummyId = 0


With rs
    If Not .EOF Then
    'first record
      .MoveFirst

        patientID = rs.Fields(1) '
        eventID = rs.Fields(2) '
        .Edit
        rs.Fields(0) = dummyId + 1
        .Update
        .MoveNext

        Do While Not .EOF
          'store the values from the last record
          lastpatientID = patientID
          lasteventID = eventID

          'get the new values

          patientID = rs.Fields(1) '
          eventID = rs.Fields(2) '

          'new patient or new hospital stay
          If patientID <> lastpatientID Or eventID <> lasteventID Then
            dummyId = 0 'reset back to 1
          Else
            dummyId = dummyId + 1
          End If

          .Edit
          rs.Fields(0) = dummyId + 1
          .Update
          .MoveNext

        Loop
      End If
    End With

rs.Close

Set rs = Nothing
Set dbs = Nothing

MsgBox "Finished", vbExclamation

End Sub

Затем, если для отображения данных используется кросс-таблица:

TRANSFORM First(Inpat.[Diagnosis_Code]) AS FirstOfDiagnosis_Code
SELECT Inpat.[Patient_id], Inpat.[Event_ID], Count(Inpat.[Diagnosis_Code]) 
AS [Total Of Diagnosis_Code]
FROM Inpat
GROUP BY Inpat.[Patient_id], Inpat.[Event_ID]
PIVOT Inpat.[Dummy_id];
0 голосов
/ 11 мая 2018

Благодарим Раджата Джайсвала, LeasMaps и Тима Бигелайзена за ваш вклад. Очень ценится.

Ключевым было предложение добавить дополнительный столбец к исходной таблице для использования в качестве заголовков столбцов в преобразованной таблице. Это оказалось относительно легко сделать (я сделал это в MS Excel).

Итак, моя исходная таблица была отредактирована так, чтобы выглядеть так ...

--------------------------------------------------------------
Patient_ID |  Event_ID   | Diagnosis_Code | DiagCode_Counter |
--------------------------------------------------------------
Pers001    | HospStay001 |     C139       | Diagnosis_Code_1 |
Pers001    | HospStay001 |     I245       | Diagnosis_Code_2 |
Pers001    | HospStay001 |     D456       | Diagnosis_Code_3 |
Pers001    | HospStay002 |     C139       | Diagnosis_Code_1 |
Pers001    | HospStay002 |     J123       | Diagnosis_Code_2 |
Pers555    | HospStay001 |     D312       | Diagnosis_Code_1 |
Pers999    | HospStay001 |     C120       | Diagnosis_Code_1 |
Pers999    | HospStay001 |     E101       | Diagnosis_Code_2 |
--------------------------------------------------------------

В новом добавленном поле "DiagCode_Counter" числовой суффикс увеличивается на 1 каждый раз, когда записывается новое значение Diagnosis_Code для уникального "Event_ID" .

Затем я смог создать запрос Crosstab в MS Access, используя поля "Patient_ID" и "Event_ID" как ROW заголовков; поле "DiagCode_Counter" для заголовков COLUMN ; и "Diagnosis_Code" записей как VALUES .

0 голосов
/ 10 мая 2018
CREATE  table #source (Patient_ID varchar(100), Event_ID varchar (100) ,Diagnosis_Code VARCHAR(100),Dig_Number INT)
insert into #source (Patient_ID, Event_ID,Diagnosis_Code,Dig_Number) values
('Pers001','HospStay001','I245',2),
('Pers001','HospStay001','D456',3),
('Pers001','HospStay002','C139',1),
('Pers001','HospStay002','J123',2),
('Pers555','HospStay001','D312',1),
('Pers999','HospStay001','C120',1),
('Pers999','HospStay001','E101',2),
('Pers001','HospStay001','C139',1)


--DROP TABLE tempdb..#source


DECLARE @cols AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX)

SELECT @cols = STUFF
        (
          (
            SELECT ',' + QUOTENAME( CONVERT(VARCHAR(10),Dig_Number))
            FROM #source
            GROUP BY Dig_Number

            ORDER BY Dig_Number
            FOR XML PATH(''), TYPE
          ).value('.', 'NVARCHAR(MAX)'),
          1,1,''
        );

SET @query = 'SELECT Patient_ID,Event_ID,' + @cols + ' 
              FROM
              (
                SELECT Patient_ID,Event_ID,Diagnosis_Code,dig_number
                FROM #source
             ) x
             PIVOT
             (
                MAX(Diagnosis_Code)
                FOR Dig_Number IN (' + @cols + ')
             ) p ';

EXECUTE(@query);

будет работать, если увеличить еще один столбец, который является числом дианоза.

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