我有一个表(可能最终使用SQL Server),如下所示:
我想根据相同的标准将产品放入最终分组中。
例如prod-A,prod-B,prod-X都属于同一组,因为它们的标准行相同(不能部分匹配)。
因此我希望输出是这样的
任何帮助将不胜感激。谢谢!
答案 0 :(得分:2)
在SQL Server中,这比较棘手。您可以使用与Postgres中类似的逻辑,但使用XML的方法很糟糕。
相反,让我们从获得所有完全匹配对开始:
with i as (
select i.*, count(*) over (partition by product) as nump
from input
)
select i1.product, i2.product
from i i1 join
i i2
on i1.criteria = i2.criteria and
i1.nump = i2.nump
group by i1.product, i2.product
having count(*) = i1.nump; -- everything matches
从这里开始,我们可以汇总以获得排名:
with i as (
select i.*, count(*) over (partition by product) as nump
from input
)
select i1.product, min(i2.product) as grp_product,
dense_rank() over (order by min(i2.product)) as grp
from (select i1.product, i2.product
from i i1 join
i i2
on i1.criteria = i2.criteria and
i1.nump = i2.nump
group by i1.product, i2.product
having count(*) = i1.nump -- everything matches
) ii
group by i1.product;
对于每个产品,现在分配组号。
您可以使用join
为每行分配值。
虽然您可以在Postgres中使用相同的技术,但我认为数组聚合是一种更简单的方法。
答案 1 :(得分:0)
这可能是有史以来最低效的查询,但它确实能够完成这项工作:
SELECT t.product, t.criteria, final.final_grouping
FROM t
INNER JOIN
(SELECT p.product, groups.final_grouping
FROM
(SELECT DISTINCT product, STUFF(
(SELECT DISTINCT ',' + criteria
FROM t sub
WHERE t.product = sub.product
FOR XML PATH ('')
)
, 1, 1, '') AS criterias
FROM t
GROUP BY product) p
INNER JOIN
(SELECT ROW_NUMBER() OVER(ORDER BY criterias) AS final_grouping, c.criterias
FROM
(SELECT DISTINCT STUFF(
(SELECT DISTINCT ',' + criteria
FROM t sub
WHERE t.product = sub.product
FOR XML PATH ('')
)
, 1, 1, '') AS criterias
FROM t) c) groups
ON p.criterias = groups.criterias) final
ON t.product = final.product
您可以在此处验证:http://rextester.com/SZUECY8704