Создать столбец varchar со смешанными значениями из других столбцов в SQL - PullRequest
0 голосов
/ 12 июня 2018

У меня есть такой сценарий:

CREATE TABLE tbl(templateId INT, id INT, name NVARCHAR(50), value NVARCHAR(50), row INT);

INSERT INTO tbl(templateId, id, name, value, row) 
VALUES
(1, 12, 'question1', '5 To 10', 1),
(2, 12, 'question2', 'washing machine', 1),
(3, 12, 'question3', 'yes', 1),
(4, 12, 'question2', 'tv', 2),
(5, 12, 'question1', '11 To 15', 2),
(6, 12, 'question1', '16 To 20', 2),
(7, 12, 'question4', 'employed' 2);

Данные должны быть сгруппированы по идентификатору и строке, и мне потребуется другой столбец с данными, подобными этим:

-Если мы имеемразные вопросы в одной строке (сгруппированы по id = 12 и row = 1):

(question1: (5 To 10) [AND] question2: (washing machine) [AND] question3: (yes))

-Если у нас разные вопросы в одной строке и один из них имеет много ответов, он должен выглядеть следующим образом (id = 12 и row = 2):

(question2: (tv) [AND] question1: (11 To 15, 16 To 20) [AND] question4: (employed))

Мне удалось создать первый случай, но у меня проблемы со вторым.Для второго я создал что-то вроде

(question2: (tv) [AND] question1: (11 To 15) OR question1:(16 To 20) OR question4:(employed)) 

, но это нехорошо, ответы на вопрос 1 должны быть разделены запятой, а имя не должно отображаться каждый раз.Более того, он ставит [И] только между первыми двумя именами, он также должен быть между вопросом 1 [И] вопросом 4, я просто не знаю, как заменить это ИЛИ ...

Я создалвот такая функция:

declare @result varchar(1000), @name1 varchar(250), @name2 varchar(250), 
@duplicates int;
set @result = '';
set @duplicates = 0;
set @name1 = '';
set @name2 = '';

SELECT @result = @result + ' [AND] ' +  t.name + ': (' + t.value + ')',
@duplicates = (len(@result) - len(replace(@result,t.name,''))) / 
LEN(t.name)
FROM tbl t
WHERE t.id = @table_id and t.row = @row

if(len(@result)>0)
  if (@duplicates > 1) 
    begin
         SET @result =replace(substring(@result, 7, LEN(@result) - 4), ' 
 [AND] ', ' OR ');
         SET @name1 = LEFT(@result,CHARINDEX(': ',@result)-1);
         SET @name2 = SUBSTRING(SUBSTRING(@result,CHARINDEX('OR ', @result) 
 + 2,LEN(@result)), 0,CHARINDEX(':', @result) + 0)

         if (@name1 <> @name2)
         begin
            SET @result=STUFF(@result, CHARINDEX('OR', @result), LEN('OR'), 
 '[AND]')
         end 
    end 
else
    begin
         SET @result=substring(@result, 7, LEN(@result) - 4);  
    end

return @result;  

Надеюсь, мне удалось прояснить, чего я хочу достичь.Каждое предложение будет высоко оценено.Спасибо!

1 Ответ

0 голосов
/ 13 июня 2018

Дайте этому шанс

Пример

;with cte as (
Select top 1 with ties
       [id]
      ,[row]
      ,[name]
      ,TempValue =  Stuff((Select ', ' + value From tbl Where [Row]=A.[Row] and [Name]=A.[Name] For XML Path ('')),1,2,'')
      ,RN        =  Row_Number() over (Partition By [id],[row] Order by templateId)
 From tbl A
 Order by Row_Number() over (Partition By ID,[name],row order by templateid)
)
Select [Row]
      ,NewValue = '('+Stuff((Select ' [AND] ' +concat(Name,': (',TempValue,')') From cte Where [Row]=A.[Row] Order by RN For XML Path ('')),1,7,'')+')'
 From cte A
 Group By [Row]

Возвращает

Row NewValue
1   (question1: (5 To 10) [AND] question2: (washing machine) [AND] question3: (yes))
2   (question2: (tv) [AND] question1: (11 To 15, 16 To 20) [AND] question4: (employed))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...