按聚合列分组

时间:2014-04-15 06:45:29

标签: sql sql-server-2008 tsql aggregate-functions aggregate

我需要显示与给定窗口小部件关联的数据列表,但是我只能在窗口小部件按顺序聚合(基本上在窗口小部件更改时打破运行总计)。

这有点像我的意思......

示例数据:

ID    WIDGET    PART
1     A000      B22
2     A000      B23
3     A002      B24
4     A001      B25
5     A001      B26
6     A000      B27

期望的输出:

WIDGET    MINPART    COUNT
A000      B22        2
A002      B24        1
A001      B25        2
A000      B27        1

在SQL Server中,我尝试运行以下命令:

with a as (
select 
        WIDGET, 
        min(PART) over (partition by WIDGET) as MINPART, 
        1 tcount
from test ) 
select WIDGET, MINPART, sum(tcount)
from a
group by WIDGET, MINPART

但这只会导致您可能期望的通常聚合。即:

WIDGET    MINPART    COUNT
A000      B22        3
A002      B24        1
A001      B25        2

4 个答案:

答案 0 :(得分:0)

您是不是要使用指定的列?,即

with a as (
select 
        WIDGET, 
        min(PART) over (partition by WIDGET) as MINPART, 
        1 tcount
from Widget ) 
select WIDGET, MINPART, sum(tcount)
from a
group by Widget, MinPart;

SqlFiddle here

答案 1 :(得分:0)

这对你有用吗?

;with x as (
    select *,
    lag(widget) over(order by id) as lg
    from #t
),
y as (
    select *, sum(case when widget<>lg then 1 else 0 end) over(order by id) as grp
    from x
)
select widget, min(part), count(*)
from y
group by widget, grp

答案 2 :(得分:0)

我们可以使用派生表以其他方式编写这个

DECLARE @Widget  TABLE 
(ID INT,
Widget  NVARCHAR(10),
PART NVARCHAR(10));

INSERT INTO @Widget VALUES 
(1, 'A000', 'B22'),
(2, 'A000', 'B23'),
(3, 'A002', 'B24'),
(4, 'A001', 'B25'),
(5, 'A001', 'B26'),
(6, 'A000', 'B27');


IF OBJECT_ID('tempdb..#t1') IS NOT NULL
    DROP TABLE #t1
select  Widget,PART,1 as t into #t1  from
(select Widget,MIN(PART)OVER (PARTITION BY Widget) As Part from  @Widget
GROUP BY Widget,ID,PART)AS F

select Widget,PART,SUM(t)  from #t1
group by Widget, Part

答案 3 :(得分:0)

@dean解决方案很简洁,但纯粹的SQLServer 2008解决方案是可能的,这个想法是一样的,排名公式

sum(case when widget<>lg then 1 else 0 end) over(order by id) as grp

可以通过运行总计伪造,对于记录,完整查询是

WITH part AS (
SELECT a.id, a.widget, a.part
     , breaker = CASE WHEN a.widget<>coalesce(b.widget, a.widget)
                      THEN 1
                      ELSE 0
                 END
FROM   Widgets a
       LEFT JOIN Widgets b ON a.id = b.id + 1
)
, DATA AS(
SELECT a.id, a.widget, a.part
     , rank = (SELECT sum(breaker) FROM part b WHERE a.id >=  b.id)
FROM   part a
)
SELECT widget
     , minpart = min(part)
     , [count] = count(1)
FROM DATA
GROUP BY widget, rank