我想知道从堆栈顶部开始的颜色以及多少顺序颜色,但是仅从顶部的位置1开始:
颜色位置 在堆栈中
+ red + 1
| red | 2
| red | 3
| blue | 4 Stack A
| blue | 5
| red | 6
| red | 7
+---------+
| red | 1 Stack B
+---------+
| blue | 1
| red | 2
| red | 3 Stack C
| blue | 4
+---------+
表格:
Stack Color position
A Red 1
A Red 2
A Red 3
A blue 4
A Blue 5
A Red 6
A Red 7
B Red 1
C blue 1
C red 2
C red 3
C blue 4
我不会的结果
Stack Color Quantity
A Red 3
B Red 1
C Blue 1
答案 0 :(得分:1)
简短版本
DENSE_RANK可用于查找每叠颜色的第一个“岛”并将其聚合:
with islands as (
select stack,color,position,
position-dense_rank() over (partition by stack,color order by position) i
from @table
)
select stack,color,count(*) as Count
from islands
where i=0
group by stack,color
order by stack,color
这产生了:
stack color Count
A Red 3
B Red 1
C blue 1
说明
这称为Islands problem-如何在一组数据中查找具有相同或连续值的“岛”。
Position
在这里有帮助,因为它可以更改每个`stack中的行为。我们现在需要的是通过堆栈中的颜色 查找孤岛。我们可以通过按堆栈和颜色计算DENSE_RANK来做到这一点。
declare @table table (Stack varchar(2),Color varchar(10),Position int)
insert into @table(Stack ,Color ,position)
values
('A','Red' ,1),
('A','Red' ,2),
('A','Red' ,3),
('A','blue' ,4),
('A','Blue' ,5),
('A','Red' ,6),
('A','Red' ,7),
('B','Red' ,1),
('C','blue' ,1),
('C','red' ,2),
('C','red' ,3),
('C','blue' ,4)
select
stack,color,position,
dense_rank() over (partition by stack,color order by position) as Rank
from @table
order by stack,position;
结果是:
stack color position Rank
A Red 1 1
A Red 2 2
A Red 3 3
A blue 4 1
A Blue 5 2
A Red 6 4
A Red 7 5
B Red 1 1
C blue 1 1
C red 2 1
C red 3 2
C blue 4 2
在每种颜色内部,密集等级和位置之间的差异是相同的。我们可以用它来识别岛屿:
select
stack,color,position,
dense_rank() over (partition by stack,color order by position) as Rank,
position-dense_rank() over (partition by stack,color order by position) as Island
from @table
order by stack,position
这产生了:
stack color position Rank Island
A Red 1 1 0
A Red 2 2 0
A Red 3 3 0
A blue 4 1 3
A Blue 5 2 3
A Red 6 4 2
A Red 7 5 2
B Red 1 1 0
C blue 1 1 0
C red 2 1 1
C red 3 2 1
C blue 4 2 2
我们现在可以按堆栈,颜色和孤岛分组以获得最终结果:
with x as (
select stack,color,position,dense_rank() over (partition by stack,color order by position) r,
position-dense_rank() over (partition by stack,color order by position) i
from @table
)
select stack,color,count(*) as Count
from x
where i=0
group by stack,color
order by stack,color
答案 1 :(得分:0)
这不必被视为是一个空白问题。我认为最简单的解决方案是:
select stack, first_color, count(*)
from (select t.*,
min(case when color <> first_color then position end) over (partition by stack) as first_other_color_position
from (select t.*, first_value(color) over (partition by stack order by position) as first_color
from t
) t
) t
where first_other_color_position is null or position < first_other_color_position
group by stack, first_color
order by stack;
Here是db <>小提琴。
逻辑很简单: