Проверка условия, одно / несколько значений для нескольких столбцов с разделенным запятыми столбцом - PullRequest
3 голосов
/ 02 июля 2019

У меня есть следующие данные:

create table mtest
(
 id1 int,
 id2 int,
 id3 int,
 id4 int,
 name varchar(20)
);


insert into mtest values(1,11,2,33,'Test1');
insert into mtest values(2,12,4,3,'Test2');
insert into mtest values(4,13,6,44,'Test3');
insert into mtest values(7,15,17,4,'Test4');
insert into mtest values(10,65,9,5,'Test5');
insert into mtest values(7,65,4,5,'Test6');
insert into mtest values(37,11,4,15,'Test7');

Я хочу найти идентификатор со значениями: 7 и 4

Ожидаемый результат :

id_column   value   names
-------------------------------------
id3         4       Test2,Test6,Test7
id1         7       Test4,Test6
id1         4       Test3
id4         4       Test4

Попробуйте:

select distinct id_column,value,stuff((select ','+ name from mtest b where b.id1 = a.value or b.id2 = a.value or b.id3 = a.value or b.id4 =a.value for xml path('')), 1, 1,'') names
from
(
    select case when id1 in ('7','4') then 'id1'
                when id2 in ('7','4') then 'id2'
                when id3 in ('7','4') then 'id3'
                when id4 in ('7','4') then 'id4' else ''
            end as id_column,
            case when id1 in ('7','4') then id1
                when id2 in ('7','4') then id2
                when id3 in ('7','4') then id3
                when id4 in ('7','4') then id4 else ''
            end as value,
            name
    from mtest
) a
where a.id_column <> ''

Но получаю неправильный результат:

id_column   value   names
---------------------------------------------------
id1         4       Test2,Test3,Test4,Test6,Test7
id1         7       Test4,Test6
id3         4       Test2,Test3,Test4,Test6,Test7   

А также меня беспокоит предложение stuff для множественного числа или условий, поскольку в таблице содержится более 10 миллионов записей.

Ответы [ 3 ]

2 голосов
/ 02 июля 2019

Вы можете сделать UNPIVOT И XML Path, следующий запрос должен сделать то, что вы хотите:

;WITH CTE AS (
    SELECT Col, Val, Name
    FROM mtest a
    UNPIVOT (Val FOR Col IN ([id1],[id2],[id3],[id4])) unpiv
    WHERE Val IN (4,7) )

SELECT Col, Val, 
Name = STUFF(
             (SELECT ',' + Name 
              FROM CTE t1
              WHERE t1.Col = t2.Col AND t1.Val = t2.Val 
              FOR XML PATH (''))
             , 1, 1, '')
FROM CTE t2
GROUP BY Col, Val
2 голосов
/ 02 июля 2019

Во-первых, вам нужно нормализовать ваши данные (и под этим я действительно имею в виду исправить ваши данные, а не делать это на лету).Затем вы агрегируете свои строки на основе ID и IDCol (в моем примере).

WITH CTE AS(
    SELECT V.ID,
           V.IDCol,
           M.[Name]
    FROM dbo.mtest M
         CROSS APPLY (VALUES(id1,'id1'),(id2,'id2'),(id3,'id3'),(id4,'id4'))V(ID,IDCol))
SELECT C.IDCol,
       C.ID,
       STUFF((SELECT ',' + x.[Name]
              FROM CTE x
              WHERE C.IDCol = x.IDCol
                AND C.ID = x.ID
              FOR XML PATH(''),TYPE).value('.','varchar(MAX)'),1,1,'') AS Names
FROM CTE C
WHERE C.ID IN (4,7)
GROUP BY C.IDCol,
         C.IDl

DB <> fiddle

ПримечаниеВ SQL Server 2008 осталось 7 дней (расширенной) поддержки.вам действительно нужно посмотреть пути обновления как можно скорее.

1 голос
/ 02 июля 2019

Вы достигнете этого с CTE:

;with cte as
(
  select * from (
    select case when id1 in ('7','4') then 'id1'
                when id2 in ('7','4') then 'id2'
                when id3 in ('7','4') then 'id3'
                when id4 in ('7','4') then 'id4'
            end as id_name,
            case when id1 in ('7','4') then id1
                when id2 in ('7','4') then id2
                when id3 in ('7','4') then id3
                when id4 in ('7','4') then id4
            end as id_column,
            name
    from @mtest
  ) a where id_column is not null
)

select id_column, id_name,
       (select name + ',' from cte where id_column = c.id_column and id_name = c.id_name for xml path(''))
from cte c
group by id_column, id_name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...