2016-06-10 3 views
3

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

TABLE_A

id | scenario_id | entity_id 
1  1;2;3;4;5  1;3 
2  4;5;8;10  2;3 
3  1;5;8;11  1;2;4; 
4  3;5;8;9  4;5; 

Теперь, если один пользователь выбирает из одного ENTITY_ID, давайте скажем 3, то SQL запрос должен возвращать что-то похож на:

scenario_id 
1;2;3;4;5;8;10 

Или, если он выбирает 5, возвращаемый массив должен выглядеть следующим образом:

scenario_id 
3;5;8;9 

Может ли это быть сделано с использованием только операторов SQL?

+0

Просьба уточнить ... –

+5

Либо исправьте свою схему, либо не беспокойтесь, используя СУРБД. – Strawberry

+0

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

ответ

1

Для SQL Server вы можете использовать это, чтобы получить желаемый результат:

DECLARE @xml xml, @entity_id int = 3 
--Here I generate data similar to yours 
;WITH cte AS (
SELECT * 
FROM (VALUES 
(1, '1;2;3;4;5', '1;3'), 
(2, '4;5;8;10', '2;3'), 
(3, '1;5;8;11', '1;2;4;'), 
(4, '3;5;8;9', '4;5;') 
) as t(id, scenario_id, [entity_id]) 
) 
--create xml 
SELECT @xml = (
SELECT CAST('<i id="'+ CAST(id as nvarchar(10)) +'"><s>' + REPLACE(scenario_id,';','</s><s>') + '</s><e>' + REPLACE([entity_id],';','</e><e>') + '</e></i>' as xml) 
FROM cte 
FOR XML PATH('') 
) 
--Normalizing the table and getting result 
SELECT STUFF((
SELECT ';' + CAST(scenario_id as nvarchar(10)) 
FROM (
    SELECT DISTINCT t.v.value('.','int') as scenario_id 
    FROM @xml.nodes('/i/s') as t(v) 
    INNER JOIN @xml.nodes('/i/e') as s(r) 
     ON t.v.value('../@id','int') = s.r.value('../@id','int') 
    WHERE s.r.value('.','int') = @entity_id 
) as p 
FOR XML PATH('')),1,1,'') as scenario_id 

Выход для entity_id = 3:

scenario_id 
1;2;3;4;5;8;10 

entity_id = 5 Для

scenario_id 
3;5;8;9 
1

Вы можете использовать что-то вроде этого, чтобы найти идентификатор в сценарии_id, но всегда это сканирование ПОЛНОГО ТАБЛИЦА.

SELECT * 
FROM table_a 
WHERE 
FIND_IN_SET('3', REPLACE(scenario_id,';',',')) > 0; 
+0

Плюс, это ужасная идея. – Strawberry

0

Простой. НОРМАЛИЗОВАТЬ Схему ... В это грубейшее, что могло бы быть следующим ...

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL 
,scenario_id INT NOT NULL 
,entity_id INT NOT NULL 
,PRIMARY KEY (id,scenario_id,entity_id) 
); 

INSERT INTO my_table VALUES 
(1, 1,1), 
(1, 1,3), 
(1, 2,1), 
(1, 2,3), 
(1, 3,1), 
(1, 3,3), 
(1, 4,1), 
(1, 4,3), 
(1, 5,1), 
(1, 5,3), 
(2, 4,2), 
(2, 4,3), 
(2, 5,2), 
(2, 5,3), 
(2, 8,2), 
(2, 8,3), 
(2,10,2), 
(2,10,3), 
(3, 1,1), 
(3, 1,2), 
(3, 1,4), 
(3, 5,1), 
(3, 5,2), 
(3, 5,4), 
(3, 8,1), 
(3, 8,2), 
(3, 8,4), 
(3,11,1), 
(3,11,2), 
(3,11,4), 
(4, 3,4), 
(4, 3,5), 
(4, 5,4), 
(4, 5,5), 
(4, 8,4), 
(4, 8,5), 
(4, 9,4), 
(4, 9,5); 

SELECT DISTINCT scenario_id FROM my_table WHERE entity_id = 3 ORDER BY scenario_id; 
+-------------+ 
| scenario_id | 
+-------------+ 
|   1 | 
|   2 | 
|   3 | 
|   4 | 
|   5 | 
|   8 | 
|   10 | 
+-------------+ 
0

разделить сценарий_id на ';' и скопируйте во временную таблицу, чтобы использовать это для вашего запроса, используя функции instr и подстроки , это может помочь вам link, но вам нужна функция цикла для вызова вашей процедуры как ';' повторяется

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