选择每个GROUP BY组中的第一行

时间:2014-06-03 23:38:06

标签: sql sql-server greatest-n-per-group

我的项目中有一项要求是我有这些数据:

C1 | C2 | C3 | C4
A  | B  | 2  | X
A  | B  | 3  | Y
C  | D  | 4  | Q
C  | D  | 1  | P

其中C1,C2,C3和C4是数据库

中的列名

我需要显示这样的数据

C1 | C2 | C3 | C4
A  | B  | 5  | X
C  | D  | 5  | Q

3 个答案:

答案 0 :(得分:1)

假设您的意思是按c4排序的第一条记录(按c1c2分组),那么这将有助于建立row_number并使用maxcase

with cte as (
  select *,
    row_number() over (partition by c1, c2 order by c4) rn
  from yourtable
) 
select c1, c2, sum(c3), max(case when rn = 1 then c4 end) c4
from cte 
group by c1, c2

但是,如果您不想按c4订购,则需要其他一些列以确保结果的正确顺序。如果没有order by子句,则无法保证返回的方式。

答案 1 :(得分:1)

答案很简单。请按照我的解决方案:

--CREATE THE SAMPLE TABLE
CREATE TABLE TABLE1 (C1 char(1) NULL, C2 char(1) NULL, C3 int NULL, C4 char(1) NULL);
GO

--INSERT THE SAMPLE VALUES
INSERT INTO TABLE1 VALUES ('A', 'B', 2, 'X'), ('A', 'B', 3, 'Y'), ('C', 'D', 4, 'Q'), ('C','D', 1, 'P');
GO

--SELECT SUM(C3) AND GROUP BY ONLY C1 AND C2, THEN SELECT TOP 1 ONLY FROM C4
SELECT 
    C1, 
    C2, 
    SUM(C3) AS C3, 
    (SELECT TOP(1) C4 FROM TABLE1 AS B WHERE A.C1 = B.C1) AS C4 
FROM 
    TABLE1 AS A 
GROUP BY 
    C1, 
    C2;
GO

--CLEAN UP THE DATABASE, DROP THE SAMPLE TABLE
IF EXISTS(SELECT name FROM sys.tables WHERE object_id = OBJECT_ID(N'TABLE1')) DROP TABLE TABLE1;
GO

如果有帮助,请告诉我。

答案 2 :(得分:0)

我希望你选择'X'和'Q'作为首先插入的行,同时对C1和C2进行分组。 我建议你在表格中添加一个标识栏,然后按照下面的说明进行操作。

表:

DECLARE @DB TABLE (ID INT IDENTITY(1,1),C1 VARCHAR(10),C2 VARCHAR(10),C3 INT,C4 VARCHAR(10))
INSERT INTO @DB VALUES 
('A','B',2,'X'),
('A','B',3,'Y'),
('C','D',4,'Q'),
('C','D',1,'P')

代码:

SELECT  A.*,B.C4
FROM    (
        SELECT      C1,C2,SUM(C3) C3 FROM @DB
        GROUP BY    C1,C2) A
JOIN
        (
        SELECT  C1,C2,C4 FROM (
        SELECT  *,ROW_NUMBER() OVER (PARTITION BY C1,C2 ORDER BY ID) [ROW]
        FROM    @DB) LU WHERE LU.ROW = 1) B
ON      A.C1 = B.C1 AND A.C2 = B.C2

结果:

enter image description here