2015-09-26 5 views
2

Я пытаюсь раскрыть мои данные, но получить некоторые странные результаты. Как я могу это сделать?Как сделать UNPIVOT таблицей в SQL Server?

Ниже приводится мой код и скриншот из результатов. (SQL Fiddle)

select distinct recId, caseNumber, servtype, mins 
from 
(
    select 
     recid 
     ,caseNumber 
     ,[preEnrollment_type] 
     ,[preEnrollment_minutes] 
     ,[screening_type] 
     ,[screeningEnA_minutes] 
     ,[ifsp_type] 
     ,[ifsp_minutes] 
    from 
     CaseManagementProgressNote 
    where 
     [formComplete]=1 
     and [reviewed]<>1 
     and [dataentry]<>1 
     and [caseManagementEntry]=1 
     and [serviceCoordinator] <> '[email protected]' 
     and [contactDateTime] >= '1/1/2015' 
     and [childID] is not null 
) as cp 
unpivot 
(
    servType for servTypes in ([preEnrollment_type],[screening_type],[ifsp_type]) 
) as up1 
unpivot 
(
    mins for minutess in ([preEnrollment_minutes],[screeningEnA_minutes],[ifsp_minutes]) 
) as up2 
order by 
    recId 

Верхняя часть является странныеunpivot ред данных, а нижняя часть является фактической таблице.

enter image description here

Как вы можете видеть в ред данных unpivot, то [column]_type повторяется дважды и имеет неправильные соответствующие значения.

мне нужно

1439 964699 -NA- null 
1439 964699 SC  45 
1439 964699 TCM FF 20 

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

Это ссылка я использовал mssqltips

SQL Fiddle из приведенного выше примера.

+0

Существует очень хороший шанс, что вы получите полезный ответ на свой вопрос, если вы добавите в него скрипт SQL. –

+0

SQL Fiddle добавлен :) – esausilva

ответ

1

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

Если посмотреть на результаты первого UNPIVOT:

select * 
from 
(
    select 
     recid 
     ,caseNumber 
     ,[preEnrollment_type] 
     ,[preEnrollment_minutes] 
     ,[screening_type] 
     ,[screeningEnA_minutes] 
     ,[ifsp_type] 
     ,[ifsp_minutes] 
    from 
     CaseManagementProgressNote 
) as cp 
unpivot 
(
    servType for servTypes in ([preEnrollment_type],[screening_type],[ifsp_type]) 
) as up1 

Вы увидите

╔═════════╦═════════════╦════════════════════════╦═══════════════════════╦═══════════════╦═══════════╦════════════════════╗ 
║ recid ║ caseNumber ║ preEnrollment_minutes ║ screeningEnA_minutes ║ ifsp_minutes ║ servType ║  servTypes  ║ 
╠═════════╬═════════════╬════════════════════════╬═══════════════════════╬═══════════════╬═══════════╬════════════════════╣ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ -NA-  ║ preEnrollment_type ║ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ SC  ║ screening_type  ║ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ TCM FF ║ ifsp_type   ║ 
╚═════════╩═════════════╩════════════════════════╩═══════════════════════╩═══════════════╩═══════════╩════════════════════╝

должно быть ясно из этого, что вторая UNPIVOT операция делает, почему он дает вам результаты, которые он делает: чтобы получить желаемый результат от этого, вы не нужно необходимо для того, чтобы не допустить. UNPIVOT преобразует столбцы в строки. Это не то, что вы ищете. У вас уже есть нужные строки. Вы хотите разместить все три столбца minutes в одном столбце, в зависимости от servTypes. Есть способы сделать это, например, путем добавления выражения в свой SELECT список, например, так:

CASE servType 
WHEN 'preEnrollment_type' THEN preEnrollment_minutes 
WHEN 'screening_type' THEN screeningEnA_minutes 
WHEN 'ifsp_type' THEN isfp_minutes 
END 

Или использовать @ ander2ed Подход и падение UNPIVOT полностью, если вы не возражаете, что это не отфильтруйте NULL s.

В статье вы ссылаетесь на обложки этой проблемы тоже:

Единственная сложность здесь соответствие выходного телефона соответствующего типа телефона - для этого нужно сделать некоторые строки опроса, чтобы убедиться, что Phone1 матчей PhoneType1, Phone2 соответствует PhoneType2 и т. Д.

Он решает его, делая второй UNPIVOT, а затем фильтрует результаты. Вы можете заставить его работать, связав servTypes и minutess. В ваших конкретных данных образца их первый символ достаточен для идентификации и одинаковый в двух столбцах, поэтому вы можете добавить where left(servTypes, 1) = left(minutess, 1) к вашему запросу.

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

+0

Я добавил заявление 'case', и он отлично работает !! ... и спасибо за объяснение – esausilva

0

Вы можете использовать Cross Apply вместо unpivot здесь. Я считаю, что синтаксис намного легче понять, и вы сможете сохранить нулевые значения. Попробуйте что-то вроде:

select recid, casenumber, servtype, mins 
from CaseManagementProgressNote a 
cross apply (VALUES (preEnrollment_type, preEnrollment_minutes), 
        (screening_type, screeningEna_Minutes), 
        (ifsp_type, ifsp_minutes)) unpvt (servtype, mins) 
+0

Мне нравится синтаксис в этом запросе, однако он не запускается в SQL Server. Он запускается в SQL Fiddle tho. SQL Server дает мне следующую ошибку: «Неправильный синтаксис рядом с ключевым словом« VALUES ». – esausilva

+0

Интересно. Какую версию SQL вы используете? Он работает для меня в Microsoft SQL Server 2008 r2. – ander2ed

+0

SQL Server Studio 2012 на моем компьютере, однако фактическая база данных находится в SQL Server 2005 – esausilva

Смежные вопросы