Получение значения двух столбцов при повороте

#sql-server

#sql-сервер

Вопрос:

У меня есть таблица, в которой есть записи типа

 Acct    Nurse   EntryDateTime          DBCode   Answer  FormSeq
123     Sally     9/8/2020 09:22        Code1    Ans1     0001
123     Jim     9/8/2020 10:25          Code1    Ans2     0001
123     Sally    9/8/2020  09:15        Code2    C2Ans1   0001
  

У меня есть запрос, который поворачивает это, чтобы получить ответ из последней записи на основе DBCode и EntryDateTime, который отлично работает. Что мне нужно сделать, так это получить медсестру, а также ответ.

Итак, моя строка будет

 Acct   Code1    Code1Nurse     Code2      Code2Nurse
123    Ans2       Jim            C2Ans1   Sally      
  

Есть ли способ сделать это? Мне понадобится медсестра для каждого уникального кода базы данных

Вот мой сводный код:

 SELECT * FROM (
  SELECT
    [AcctNumber],
    [Answer],
   
    [DBCode],
    [EntryDate],
    [FormCode],[FormSeq]
   
  FROM V_FAC_MULTIAPP_FORM_WITH_HOURLY
) MultiApp
PIVOT (
 MAX( [Answer])
  FOR [DBCode]
  IN (
    [AST],
    [SDRM],
    [SDRF],[SDAAS],[SDDCT],[SDDAS],[SDABY],[SDDAT],[SDTRCC],[SDADMTW],[Prptic],[Pdcrt]
  )
) AS PivotTable WHERE EntryDate >='8/15/2020' and FormCode='LL003' ORDER BY EntryDate
  

Ответ №1:

Вы могли бы использовать условную агрегацию.

Данные

 drop table if exists #tTEST;
go
select * INTO #tTEST from (values 
(123, 'Sally', '9/8/2020 09:22', 'Code1', 'Ans1', '0001'),
(123, 'Jim', '9/8/2020 10:25', 'Code1', 'Ans2', '0001'),
(123, 'Sally', '9/8/2020  09:15', 'Code2', 'C2Ans1', '0001')) V(Acct, Nurse, EntryDateTime, DBCode, Answer, FormSeq);
  

Запрос

 ;with rn_cte as (
    select *, row_number() over (partition by DBCode order by EntryDateTime desc) rn
    from #tTEST)
select Acct, 
      max(case when DBCode='Code1' and rn=1 then Answer else null end) Code1,
      max(case when DBCode='Code1' and rn=1 then Nurse else null end) Code1Nurse,
      max(case when DBCode='Code2' and rn=1 then Answer else null end) Code2,
      max(case when DBCode='Code2' and rn=1 then Nurse else null end) Code2Nurse
from rn_cte
group by Acct;
  

Вывод

 Acct    Code1   Code1Nurse  Code2   Code2Nurse
123     Ans2    Jim         C2Ans1  Sally
  

Ответ №2:

Здесь есть с чем поиграть. Потребуется некоторая доработка, но вы могли бы сделать запрос динамическим для построения столбцов для выбора на основе DBCodes, которые у вас есть в вашей таблице…

 IF OBJECT_ID('tempdb..#V_FAC_MULTIAPP_FORM_WITH_HOURLY') IS NOT NULL 
DROP TABLE #V_FAC_MULTIAPP_FORM_WITH_HOURLY;

CREATE TABLE #V_FAC_MULTIAPP_FORM_WITH_HOURLY 
    (
        Acct INT,    
        Nurse VARCHAR(20),
        EntryDateTime DATETIME,
        DBCode VARCHAR(10),
        Answer VARCHAR(10),
        FormSeq VARCHAR(10)
    )
INSERT  #V_FAC_MULTIAPP_FORM_WITH_HOURLY
VALUES
    (123,'Sally','9/8/2020 09:22','Code1','Ans1','0001'),
    (123,'Jim','9/8/2020 10:25','Code1','Ans2','0001'),
    (123,'Sally','9/8/2020 09:15','Code2','C2Ans1','0001');


WITH    Top_Row_Per_DBCode_By_EntryDate AS
(
    SELECT  ROW_NUMBER() OVER (PARTITION BY DBCode ORDER BY EntryDateTime DESC) AS top_row,
            Acct,
            DBCode,
            Nurse ':' Answer AS Answer
    FROM    #V_FAC_MULTIAPP_FORM_WITH_HOURLY
),  Filtered_CTE AS
(
    SELECT  *
    FROM    Top_Row_Per_DBCode_By_EntryDate
    WHERE   top_row = 1
)
SELECT  Acct, 
        Substring([Code1],CHARINDEX(':',[Code1]) 1,LEN([Code1])-CHARINDEX(':',[Code1])) AS Code1,
        Substring([Code1],0,CHARINDEX(':',[Code1])) AS Code1Nurse, 
        Substring([Code2],CHARINDEX(':',[Code2]) 1,LEN([Code2])-CHARINDEX(':',[Code2])) AS Code2,
        Substring([Code2],0,CHARINDEX(':',[Code2])) AS Code2Nurse
FROM    Filtered_CTE
PIVOT
(
    MAX( [Answer]) FOR [DBCode]
    IN ([Code1],[Code2])
) AS PivotTable