SQL Group By Problem

时间:2011-09-21 08:19:19

标签: sql database sql-server-2008 group-by aggregate-functions

我有一个包含3个cols的表,即points,project_id和creation_date。例如,每次分配点时都会创建新记录。

points = 20 project_id = 441 creation_date = 04/02/2011 -> Is one record
points = 10 project_id = 600 creation_date = 04/02/2011 -> Is another record
points = 5 project_id = 441 creation_dae = 06/02/2011 -> Is final record

(creation_date是输入记录的日期,通过将默认值设置为GETDATE()来实现)

现在的问题是我想得到按项目ID分组的MAX点,但我也希望creation_date与它一起出现所以我可以将它用于其他目的,如果创建日期重复它的确定而我不能按creation_date分组,因为如果我这样做会跳过id为600的项目点并且错误,因为id 600是一个不同的项目,它的唯一最大点数是10所以它应该被列出并且只有在我使用project_id进行分组时它才有可能但是我应该如何还列出creation_date

到目前为止,我正在使用此查询来获取每个项目的MAX点

SELECT MAX(指向)AS点,project_id
来自LogiCpsLogs AS LCL
WHERE(writer_id = @writer_id)AND(DATENAME(mm,GETDATE())= DATENAME(mm,creation_date))AND(点<> 0)
GROUP BY project_id

writer_id是我想看的点的作家的ID,比如writer_id = 1,2或3。

此查询仅显示当月的结果,但我也想列出creation_date。请帮忙。

4 个答案:

答案 0 :(得分:2)

子查询方式

SELECT P.Project_ID, P.Creation_Date, T.Max_Points
FROM Projects P INNER JOIN
   (
   SELECT Project_ID, MAX(Points) AS Max_Points
   FROM Projects
   GROUP BY Project_ID
   ) T 
ON P.Project_ID = T.Project_ID
AND P.Points = T.Max_Points

请参阅评论:这将为您提供达到最大分数的所有日期。如果你只想要一个,那么查询会更复杂。

编辑:

  • 误读要求。添加了额外的约束。

答案 1 :(得分:0)

我会给你样品..

SELECT MAX(POINTS),
       PROJECT_ID,
       CREATION_DATE 
  FROM yourtable
 GROUP by CREATION_DATE,PROJECT_ID;

答案 2 :(得分:0)

这应该是你想要的,你甚至不需要分组或加剧功能:

SELECT points, project_id, created_date
FROM @T AS LCL
WHERE writer_id = @writer_id AND points <> 0 
    AND NOT EXISTS (
        SELECT TOP 1 1 
        FROM @T AS T2 
        WHERE T2.writer_id = @writer_id 
            AND T2.project_id = LCL.project_id 
            AND T2.points > LCL.points)

@T是您的表格,如果您只想显示一般总数的记录,而不仅仅显示给定@writer_id的总数,则删除限制{{1}来自内部查询

我以前用来测试的代码:

T2.writer_id = @writer_id

我的结果:

DECLARE @T TABLE
(
writer_id int,
points int,
project_id int,
created_date datetime
)

INSERT INTO @T VALUES(1, 20, 441, CAST('20110204' AS DATETIME))
INSERT INTO @T VALUES(1, 10, 600, CAST('20110204' AS DATETIME))
INSERT INTO @T VALUES(1, 5, 441, CAST('20110202' AS DATETIME))
INSERT INTO @T VALUES(1, 15, 241, GETDATE())
INSERT INTO @T VALUES(1, 12, 241, GETDATE())
INSERT INTO @T VALUES(2, 12, 241, GETDATE())

SELECT * FROM @T

DECLARE @writer_id int = 1

答案 3 :(得分:0)

我的解决方案使用CROSS APPLY子查询。

为了获得最佳性能,我在project_id(ASC)&amp;上创建了一个索引。点(DESC排序顺序)字段。

如果您希望查看具有最高分的所有creation_date值,则可以使用WITH TIES

CREATE TABLE dbo.Project
(
    project_id INT PRIMARY KEY
    ,name NVARCHAR(100) NOT NULL
);
CREATE TABLE dbo.ProjectActivity
(
    project_activity INT IDENTITY(1,1) PRIMARY KEY
    ,project_id INT NOT NULL REFERENCES dbo.Project(project_id)
    ,points INT NOT NULL
    ,creation_date DATE NOT NULL
);
CREATE INDEX IX_ProjectActivity_project_id_points_creation_date
ON dbo.ProjectActivity(project_id ASC, points DESC)
INCLUDE (creation_date);
GO

INSERT  dbo.Project
VALUES  (1, 'A'), (2, 'BB'), (3, 'CCC');
INSERT  dbo.ProjectActivity (project_id, points, creation_date)
VALUES  (1,100,'2011-01-01'), (1,110,'2011-02-02'), (1, 111, '2011-03-03'), (1, 111, '2011-04-04')
        ,(2, 20, '2011-02-02'), (2, 22, '2011-03-03')
        ,(3, 2, '2011-03-03');

SELECT  p.*, ca.*
FROM    dbo.Project p
CROSS APPLY
(
        SELECT  TOP(1) WITH TIES
                pa.points, pa.creation_date 
        FROM    dbo.ProjectActivity pa
        WHERE   pa.project_id = p.project_id 
        ORDER BY pa.points DESC
) ca;

DROP TABLE dbo.ProjectActivity;
DROP TABLE dbo.Project;