TSQL Как объединить столбец из объединенной таблицы с группировкой по - PullRequest
0 голосов
/ 22 сентября 2018

У меня есть 2 связанные таблицы: Producto и Productos_ProductosRelacionados

    Producto                Productos_ProductosRelacionados
|id|referencia|         |id|idProducto|idProductoRelacionado|
|1 |    A     |         |1 |    1     |  2                  |
|2 |    B     |         |2 |    1     |  3                  |
|3 |    C     |         |3 |    3     |  4                  |
|4 |    D     |         |4 |    3     |  5                  |
|5 |    E     |

Мне нужно это:

|idProducto|referencia|
|   1      |  B,C     | 
|   2      |          | 
|   3      |  D,E     |

У меня более старый SQL-сервер, поэтому не может использовать STRING_AGG ,До сих пор я достигал только конкатенации idProductoRelacionado :

|idProducto|idProductoRelacionado|
|   1      |  2,3                |

с:

SELECT pr1.idProducto
 ,STUFF((
          SELECT ',' + CONVERT(varchar, pr.idProductoRelacionado) 
          FROM [Productos_ProductosRelacionados] as pr
          WHERE pr.idProducto = pr1.idProducto        
          FOR XML PATH('')), 1, 1, '') as RelacionadosID
 FROM [dbo].[Producto] as p1 
 join [Productos_ProductosRelacionados] as pr1 on p1.id = pr1.idProductoRelacionado
 GROUP BY pr1.idProducto

Если я попробую тот же подход для конкатенации referencia columnон дает мне: «Столбец« dbo.Producto.id »недопустим в списке выбора, поскольку он не содержится ни в статистической функции, ни в предложении GROUP BY».

select pr1.idProducto
,STUFF((
          SELECT ',' + p.referencia
          FROM [dbo].[Producto] as p
          WHERE p.id = p1.id  
          FOR XML PATH('')), 1, 1, '') as RelacionadosREF
 from [dbo].[Producto] as p1 
 join [Productos_ProductosRelacionados] as pr1 on p1.id = pr1.idProductoRelacionado
 GROUP BY pr1.idProducto

Я не понимаю разницы между двумя запросами, почему первый работает, а второй нет.

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

Простое соединение должно работать.Проверьте SQLFiddle

SELECT 
  id,
  (SELECT
     cast (p1.referencia as varchar(100)) + ','
   FROM producto p
   LEFT JOIN Productos_ProductosRelacionados pr
         on pr.idProduct = p.id
   LEFT JOIN producto p1
         on p1.id = pr.idProductoRelacionado
   WHERE p.id = src.id
   FOR XML PATH('')) as referencia
FROM
   producto src;
0 голосов
/ 22 сентября 2018

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

--Create tables for example
select * into #Producto from (
 select 1 id,'A' referential union all select 2,'B' union all select 3,'C' union all select 4,'D' union all select 5,'E'
 ) tmp;

select * into #Productos_ProductosRelacionados from (
select 1 id,1 idProducto,2 idProductoRelacionado union all select 2,1,3 union all select 3,3,4 union all select 4,3,5
) tmp;


-- Recurse query    
With tmp as (
select ROW_NUMBER() over(partition by f1.ID order by f1.id, f3.referential desc) RangID,
count(*)  over(partition by f1.ID order by f1.id) NbID, 
f1.id, f3.referential 
from #Producto f1
left outer join #Productos_ProductosRelacionados f2 on f1.id=f2.idProducto
left outer join #Producto f3 on f2.idProductoRelacionado=f3.id
),
Recurse as (
select f1.id, f1.RangID, f1.NbID, cast(f1.referential as varchar(2000)) referential, 1 rangrecur  from tmp f1 where RangID=1
union all
select f1.id, f1.RangID, f1.NbID, cast(isnull(f1.referential, '') + ',' + isnull(f2.referential, '') as varchar(2000)) referential, f2.rangrecur + 1 as rangrecur  
from tmp f1 inner join Recurse f2 on f1.id=f2.id and f1.RangID-1=f2.RangID
)
select ID, Referential from recurse
where NbID=rangrecur
order by ID;
0 голосов
/ 22 сентября 2018

Я столкнулся с этим некоторое время назад.Вы должны добавить объединение к своему заявлению материала:

create table    #prod   (
                        id  int,
                        ref varchar(1)
                    )

insert into     #prod values
(1,'A'),
(2,'B'),
(3,'C'),
(4,'D'),
(5,'E')

create table    #prod_rel   (
                                id      int,
                                pid     int,
                                id_rel  int
                            )

insert into     #prod_rel values
(1,1,2),
(2,1,3),
(3,3,4),
(4,3,5)



select  distinct
        pid
        ,STUFF(
                 (SELECT ',' + c.ref FROM #prod_rel b inner join #prod c on c.id = b.id_rel where b.pid = a.pid FOR XML PATH ('')), 1, 1, ''
               )
from    #prod_rel a

drop table  #prod
            ,#prod_rel
...