有没有办法从来自 SQL 服务器中一对多关系的列表中执行 GROUP BY?

Is there a way to perform a GROUP BY from a list coming from a One-To-Many relationship in SQL Server?

我有两个表,

tb_product

Id       typeProduct
1         Type1
2         Type1
3         Type1

产品 1、2 和 3 由于 typeProduct 相同,但每个产品也具有区分它们的链接属性。

tb_product_属性

idProduct   typeAttribute  valueAttribute
    1         Attr1         Value1 
    1         Attr2         Value3
    2         Attr1         Value1
    2         Attr2         Value3
    3         Attr1         Value2
    3         Attr3         Value3

因此,产品 1 和 2 将因属性和属性值而异,因为 3 会有所不同,因为它的第二个属性的值与其他属性的第二个属性不同。

理想的结果应该是这样,因为我知道它们之间相等的细节,但我不知道这种结果是否可能。

total_rows  typeProduct   typeAttribute     valueAttribute
    2         Type1       Attr1, Attr2      Value1, Value3
    1         Type1       Attr1, Attr3      Value2, Value3

您必须先对属性和值进行分组,然后对每一行进行计数

WITH cte AS (
SELECT p.typeproduct,
       t.idproduct,
       STUFF(( SELECT ', ' + typeattribute
                FROM tb_product_attribute 
                WHERE idproduct = t.idproduct
                FOR XML PATH(''),TYPE)
                .value('.','NVARCHAR(MAX)'),1,2,'') AS typeattribute,
       STUFF(( SELECT ', ' + typevalue
                FROM tb_product_attribute 
               WHERE idproduct = t.idproduct
                FOR XML PATH(''),TYPE)
                .value('.','NVARCHAR(MAX)'),1,2,'') AS typevalue      
  FROM tb_product_attribute t
 INNER JOIN tb_product p
    ON t.idproduct = p.id
 GROUP BY p.typeproduct,
          t.idproduct
)

SELECT COUNT(*) total_rows,
       typeproduct,
       typeattribute,
       typevalue
  FROM cte
 GROUP BY typeproduct,
          typeattribute,
          typevalue

结果

total_rows  typeproduct typeattribute   typevalue
2           Type1       Attr1, Attr2    Value1, Value3
1           Type1       Attr1, Attr3    Value2, Value3

或没有 CTE

select  count(valueattribute) total_rows, 
        typeProduct, 
        typeAttribute, 
        valueAttribute 
from 
(select 
    (select top 1 tp.typeProduct 
        from tb_product as tp 
            where tp.Id = p.idProduct) as typeProduct,
    stuff((
        SELECT ', ' + [valueAttribute] 
        FROM tb_product_attribute 
        WHERE (idproduct = p.idproduct) 
        FOR XML PATH('')), 1,2,'') AS valueAttribute,
    stuff((
        SELECT ', ' + [typeAttribute]
        FROM tb_product_attribute 
        WHERE (idproduct = p.idproduct) 
        FOR XML PATH('')), 1,2,'') AS typeAttribute 
    from tb_product_attribute as p
        group by idproduct
) as subs
group by valueattribute, typeProduct, typeAttribute

试一试

create table tb_product  
  ( 
     id           INT 
     ,typeproduct CHAR(5) 
  ) 
create table tb_product_attribute  (
idProduct int,   typeAttribute char(5), valueAttribute char(6)
)
GO


CREATE Function dbo.TypeAttribute2Comma(@idProduct int)
returns varchar(max)
BEGIN
    declare @tmp varchar(max) 
    SET @tmp = '' 
    select @tmp = @tmp + typeAttribute + ', ' from tb_product_attribute where idProduct = @idProduct
    RETURN (select SUBSTRING(@tmp, 0, LEN(@tmp))) 

END 
GO

CREATE Function dbo.ValueAttribute2Comma(@idProduct int)
returns varchar(max)
BEGIN
    declare @tmp varchar(max) 
    SET @tmp = '' 
    select @tmp = @tmp + typeAttribute + ', ' from tb_product_attribute where idProduct = @idProduct
    RETURN (select SUBSTRING(@tmp, 0, LEN(@tmp))) 

END 
GO

INSERT tb_product 
       (id ,typeproduct) 
VALUES ( 1 ,'Type1'), 
       (2 ,'Type1'), 
       (3 ,'Type1') 

insert tb_product_attribute( idProduct   ,typeAttribute  ,valueAttribute) values
    (1, 'Attr1', 'Value1'), 
    (1, 'Attr2', 'Value3'),
    (2, 'Attr1', 'Value1'),
    (2, 'Attr2', 'Value3'),
    (3, 'Attr1', 'Value2'),
    (3, 'Attr3', 'Value3')

GO

select 
* 
,dbo.TypeAttribute2Comma(id) TypeAttribute2
,dbo.ValueAttribute2Comma(id) ValueAttribute2
from tb_product

结果

id          typeproduct TypeAttribute2 ValueAttribute2 
----------- ----------- -------------- ----------------
1           Type1       Attr1, Attr2   Attr1, Attr2
2           Type1       Attr1, Attr2   Attr1, Attr2
3           Type1       Attr1, Attr3   Attr1, Attr3