sql >> Base de Datos >  >> RDS >> Sqlserver

Quiero hacer group_concat en SQL Server

Para darle una ilustración de unirse (en este caso, una autounión, pero todas las uniones funcionan) y usar STUFF para esto. Observe la cláusula WHERE dentro de STUFF. Esto es lo que vincula el registro con los valores correctos.

declare @test table
(
email varchar(50),
address varchar(50)
)

insert into @test VALUES
('[email protected]','A123A'),  
('[email protected]','AB263'),   
('[email protected]','45632A'),   
('[email protected]','78YU'),
('[email protected]','6543D')

SELECT DISTINCT 
       email,
       Stuff((SELECT ', ' + address  
              FROM   @test t2 
              WHERE  t2.email  = t1.email  
              FOR XML PATH('')), 1, 2, '') Address
FROM   @test t1  

Editar

Bien, entonces lo que quieres (lo que realmente, realmente quieres) es:

declare @customers table
(
emailaddress varchar(50),
customerid int
)

insert into @customers VALUES
('[email protected]',1),  
('[email protected]',2)   

declare @orders table
(
orderid int,
customerid int,
orderdate date
)

insert into @orders VALUES
(1, 1, '2017-06-02'),
(2, 1, '2017-06-05'),
(3, 1, '2017-07-13'),
(4, 2, '2017-06-13')

declare @orderdetails table
(
id int,
orderid int,
productcode varchar(10)
)

insert into @orderdetails VALUES
(1, 1, 'apple pie'),
(2, 1, 'bread'),
(3, 2, 'custard'),
(4, 2, 'orange'),
(5, 3, 'orange'),
(6, 4, 'orange')

SELECT DISTINCT c.EmailAddress, productcode=
STUFF((SELECT ',' + odc.productcode FROM 
(SELECT DISTINCT emailaddress,productcode FROM 
@orders o2 inner join @orderdetails od2 on
o2.orderid = od2.orderid
inner join @customers c2 ON c2.customerid = o2.customerid) odc 
WHERE odc.emailaddress=c.emailaddress 
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM @OrderDetails od 
JOIN @Orders o ON od.OrderID = o.OrderID 
JOIN @Customers c ON c.CustomerID=o.CustomerID 
WHERE o.OrderDate BETWEEN '2016-01-01' AND getdate()

Note el cambio aquí. El SELECCIONAR en STUFF ahora proviene de una subconsulta, por lo que puede agrupar por dirección de correo electrónico.

Explicación adicional

Su objetivo es tener una concatenación de códigos de productos agrupados por cliente (representado por dirección de correo electrónico). El problema es que los códigos de producto están en la tabla de detalles del pedido y la dirección de correo electrónico está en la tabla de clientes, pero no hay ningún campo que los vincule. La tabla de clientes tiene una relación de uno a muchos con la tabla de pedidos y la tabla de pedidos tiene una relación de uno a muchos con la tabla de detalles de pedidos. Ese es un nivel de abstracción demasiado. Por lo tanto, debemos ayudar a la base de datos al proporcionar un enlace directo entre el código de producto y la dirección de correo electrónico. Esto lo hacemos a través de la Sub-consulta. Espero que esto lo aclare más.