【问题标题】:SQL Group By a Partition BySQL Group By 分区 By
【发布时间】:2020-04-27 00:20:00
【问题描述】:

这必须在 MS SQL Server 中完成。我相信必须使用OVER( PARTITION BY),但我的所有尝试都失败了,我最终将记录计数到每个 ID 或其他东西......

我有这张桌子:

| ID   | COLOR  |
+------+--------+
| 1    | Red    |
| 1    | Green  |
| 1    | Blue   |
| 2    | Red    |
| 2    | Green  |
| 2    | Blue   |
| 3    | Red    |
| 3    | Brown  |
| 3    | Orange |

请注意,ID = 1 和 ID = 2 的 COLOR 值完全相同,但 ID = 3 仅共享值 COLOR = Red。

我想将表格分组如下:

| COLOR  | COUNT | GROUPING |
+--------+-------+----------+
| Red    | 2     | Type 1   |
| Green  | 2     | Type 1   |
| Blue   | 2     | Type 1   |
| Red    | 1     | Type 2   |
| Brown  | 1     | Type 2   |
| Orange | 1     | Type 2   |

这意味着 ID = 1 和 ID = 2 共享相同的 3 个颜色值,它们作为类型 1 聚合在一起。虽然 ID = 3 与 ID = 1 和 ID = 2 共享一个颜色值(即'Red') 其余值不共享,因此被视为类型 2(不同分组)。

使用的表是简单的示例,足以复制到整个数据集,但是理论上每个 ID 可以有数百条记录,每行的颜色值不同。但是它们是唯一的,一个 ID 在不同的行中不能具有相同的颜色。

我的最佳尝试:

SELECT
    ID, 
    COLOR,
    CONCAT ('TYPE ', COUNT(8) OVER( PARTITION by ID)) AS COLOR_GROUP
FROM 
    {TABLE};

结果:

| ID   | COLOR  | GROUPING |
+------+--------+----------+
| 1    | Green  | Type 3   |
| 1    | Blue   | Type 3   |
| 1    | Red    | Type 3   |
| 2    | Green  | Type 3   |
| 2    | Blue   | Type 3   |
| 2    | Red    | Type 3   |
| 3    | Red    | Type 3   |
| 3    | Brown  | Type 3   |
| 3    | Orange | Type 3   |

虽然结果很糟糕,但我尝试了不同的方法,但没有一个更好。

希望我已经足够清楚了。

感谢您的帮助!

【问题讨论】:

  • 另外请告诉我们您的失败尝试。
  • 完成!我的尝试很糟糕,我知道,它确实没有传达我所做的测试和搜索,但它仍然是我可以获得的最好的结果,可以解释,而不是完全胡言乱语。
  • 为什么RED 出现两次?你想要这两种类型??
  • 是的,RED 实际上是共同因素,但没关系。将每个 ID 的记录一起读取的图像,如 ID = 1 上的 (RED, GREEN, BLUE) 与 ID = 2 上的 (RED, GREEN, BLUE) 相比,因为它们匹配它们被计算两次。与 ID = 3 上的 (RED, BROWN, ORANGE) 相比,它们不匹配,因此 ID = 3 以不同的类型聚合,并且只计算一次。

标签: sql-server group-by partition-by


【解决方案1】:

尝试以下方法:

declare @t table ( ID  int,COLOR varchar(100))
insert into @t select 1   ,'Red'    
insert into @t select 1   ,'Green'  
insert into @t select 1   ,'Blue'   
insert into @t select 2   ,'Red'    
insert into @t select 2   ,'Green'  
insert into @t select 2   ,'Blue'   
insert into @t select 3   ,'Red'    
insert into @t select 3   ,'Brown'  
insert into @t select 3   ,'Orange'


select *, STUFF((SELECT CHAR(10) + ' '+COLOR
                  FROM @t t_in where t_in.ID=t.ID
                  order by COLOR
                   FOR XML PATH ('')) , 1, 1, '') COLOR_Combined 
into #temp
from @t t

select COLOR, count(color) [COUNT], 'TYPE ' + convert(varchar(10), dense_rank() OVER (order by [grouping])) [GROUPING]
from
(   
    select id, COLOR, COLOR_Combined,  (row_number() over (order by id) - row_number() over (partition by Color_Combined order by id)) [grouping]
    from #temp
)t
group by COLOR, [grouping]
drop table if exists #temp

请找到 dbfiddle here

【讨论】:

  • 太棒了!从我可以从小提琴中收集到的东西,这正是我想要的。我将在今天晚些时候对其进行测试,以查看对我的整个数据集的复制。谢谢。
  • 经过测试并按预期工作。适用于数据集的细微调整,总体而言是一个出色的解决方案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多