Как написать запрос SQL Server, чтобы показать разделенные запятыми столбцы дочерней таблицы, левое соединение с родительской таблицей

#sql #sql-server #sql-server-2017

#sql #sql-server #sql-server-2017

Вопрос:

Я использую базу данных SQL Server, в которой есть таблицы, определенные ниже. Мне нужно написать запрос T-SQL, чтобы показать, что столбцы дочерней таблицы, разделенные запятыми, соединяются слева с родительской таблицей.

Родительская таблица

 pid   pname
------------
p1    Ana
p2    Bana
p3    Cana
  

Дочерняя таблица

 Cid   pid   cname              gender
-------------------------------------
c1    p1    AAA-Ana            M
c2    p1    BBB-Ana            M
c3    p1    CCC-Ana            F
c4    p2    MMM-Bana           M
c5    p2    NNN-Bana           M
c6    p3    RRR-Cana           F
c7    p3    SSS-Cana           F
c8    p9    ZZZ-orphan-child   M
  

результирующий вывод запроса должен быть таким, как показано ниже

Комментарии:

1. Вы можете сделать это с помощью string_agg. Не могли бы вы, пожалуйста, вставить фактические данные, а не образец, чтобы люди здесь могли предоставить скрипку с запросом.

2. Какую версию sql-сервера вы используете?

3. Microsoft SQL Server 2017 (RTM-CU20) (KB4541283) — 14.0.3294.2 (X64)

Ответ №1:

Как было предложено, вы можете использовать приведенный ниже запрос с String_agg и регистром в SQL Server 2017 и далее.

 SELECT A.PID, A.pname, 
STRING_AGG( CASE WHEN GENDER = 'M' THEN [cname] END, ',') WITHIN GROUP(ORDER BY B.CID) CNAME_MALE,
STRING_AGG( CASE WHEN GENDER = 'F' THEN [cname] END, ',') WITHIN GROUP(ORDER BY B.CID) CNAME_FEMALE,
COUNT(CASE WHEN [gender] = 'M' THEN 1 END)  AS MALE_COUNT , COUNT(CASE WHEN [gender] = 'F' THEN 1 END)  AS FEMALE_COUNT
FROM TABLE_PARENT A INNER JOIN Table_child B
ON(A.PID = B.PID) GROUP BY A.PID, A.pname order by a.pid;
  

Ответ №2:

Вы можете объединить таблицы, а затем подсчитать группировку по pid и pname, что даст вам суммы. Для конкатенации строк мне нравится использовать функцию stuff:

 select  P.pid,
        P.pname,
        cname_Male = (stuff((Select ', '   cname
                                 from childTable 
                                 where pid = P.pid and gender = 'M'
                                 for xml path ('')), 1, 2, '')),
        cname_Female = (stuff((Select ', '   cname
                                from childTable 
                                where pid = P.pid and gender = 'F'
                                for xml path ('')), 1, 2, '')),  
        MaleCount = (Select count(1) From childTable where pid = P.pid and gender = 'M'),
        FemaleCount = (Select count(1) From childTable where pid = P.pid and gender = 'F')
from parentTable P
Join childTable C ON C.pid = P.pid
group by P.pid, P.pname
  

Вывод:

введите описание изображения здесь