SQL Группировать по разделу по - PullRequest
0 голосов
/ 27 апреля 2020

Это должно быть выполнено на сервере MS SQL. Я считаю, что 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 (то есть «красный»), остальные значения не являются общими, поэтому он считается типом 2 (другая группировка).

Используемые таблицы являются простыми примерами и их достаточно для репликации в всего набора дат, однако теоретически каждый идентификатор может иметь сотни записей с разными значениями цветов в каждой строке. Однако они уникальны, один идентификатор не может иметь одинаковый цвет в разных строках.

Моя лучшая попытка:

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   |

Хотя результаты ужасны, я пробовал разные методы, но ни один из них не лучше.

Надеюсь, я был достаточно ясен.

Спасибо за помощь!

1 Ответ

0 голосов
/ 27 апреля 2020

попробуйте следующее:

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

Пожалуйста, найдите дб <> fiddle здесь .

...