SQL представление / запрос для объединения данных между 2 таблицами через поле json - PullRequest
1 голос
/ 27 сентября 2019

Пример структуры таблицы:

create table issues
(id int, title varchar(50), affectedclients varchar(max))

create table clients
(id int, name varchar(50))

insert into issues (id, title, affectedclients) values (1, 'Error when clicking save', '["1","2"]');
insert into issues (id, title, affectedclients) values (2, '404 error on url', '[3]');

insert into clients (id, name) values (1, 'Tesco');
insert into clients (id, name) values (2, 'Costa');
insert into clients (id, name) values (3, 'Boots');
insert into clients (id, name) values (4, 'Nandos');

Я хочу выполнить запрос, чтобы получить данные в следующем формате:

Id   Title                        AffectedClients
1    Error when clicking save     Tesco, Costa
2    404 error on url             Boots

КакМогу ли я достичь этого, пожалуйста, наиболее эффективным способом из возможных?

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

1 Ответ

1 голос
/ 27 сентября 2019

Вам необходимо использовать OPENJSON() с явным определением схемы для разбора текста JSON в столбце affectedclients.После этого вам нужно объединить имена (используя FOR XML PATH для SQL Server 2016+ или STRING_AGG() для SQL SQL Server 2017+).

Данные:

create table issues
(id int, title varchar(50), affectedclients varchar(max))
create table clients
(id int, name varchar(50))
insert into issues (id, title, affectedclients) values (1, 'Error when clicking save', '["1","2"]');
insert into issues (id, title, affectedclients) values (2, '404 error on url', '[3]');
insert into clients (id, name) values (1, 'Tesco');
insert into clients (id, name) values (2, 'Costa');
insert into clients (id, name) values (3, 'Boots');
insert into clients (id, name) values (4, 'Nandos');

Оператор для SQL Server 2016 +:

SELECT 
   i.id, 
   i.title,
   [affectedclients] = STUFF(
      (
      SELECT CONCAT(', ', c.[name])
      FROM OPENJSON(i.affectedclients) WITH (id int '$') j
      LEFT JOIN clients c on c.id = j.id
      FOR XML PATH('')
      ), 1, 2, '')
FROM issues i

Оператор для SQL Server 2017 +:

SELECT i.id, i.title, STRING_AGG(c.name, ', ') AS affectedclients
FROM issues i
CROSS APPLY OPENJSON(i.affectedclients) WITH (id int '$') j
LEFT JOIN clients c ON c.id = j.id
GROUP BY i.id, i.title
ORDER BY i.id, i.title

Результаты:

-----------------------------------------------
id  title                       affectedclients
-----------------------------------------------
1   Error when clicking save    Tesco, Costa
2   404 error on url            Boots
...