SQL группа по проблеме - PullRequest
       27

SQL группа по проблеме

0 голосов
/ 21 сентября 2011

У меня есть таблица с 3 столбцами, а именно: 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 ())

теперь проблема в том, что я хочу получить МАКС. Баллы, сгруппированные по project_id, но я также хочу, чтобы creation_date появлялся вместе с ним, чтобы я мог использовать его для другой цели, если дата создания повторяется, и я не могу группировать по creation_date, потому что если я при этом он пропустит точки проекта с идентификатором 600, и это неправильно, потому что идентификатор 600 - это другой проект, и его максимальные баллы равны 10, поэтому он должен быть в списке, и это возможно только в том случае, если я выполняю группировку с использованием project_id, но тогда как я должен также список create_date

Пока что я использую этот запрос, чтобы получить МАКС. Баллы за каждый проект

ВЫБРАТЬ МАКС. (Баллы) AS баллов, идентификатор проекта
ИЗ LogiCpsLogs AS LCL
WHERE (writer_id = @writer_id) AND (DATENAME (mm, GETDATE ()) = DATENAME (mm, creation_date)) AND (точки <> 0)
GROUP BY project_id

writer_id - это идентификатор писателя, чьи точки я хочу видеть, например, writer_id = 1, 2 или 3.

Этот запрос приносит результат только за текущий месяц, но я также хотел бы перечислить creation_date. Пожалуйста, помогите.

Ответы [ 4 ]

2 голосов
/ 21 сентября 2011

Способ подзапроса

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

Пожалуйста, смотрите комментарий: это даст вам ВСЕ дни, когда были достигнуты максимальные баллы.Если вам нужен только один, запрос будет более сложным.

Правки:

  • Неправильные требования.Добавлено дополнительное ограничение.
0 голосов
/ 21 сентября 2011

Мое решение использует подзапросы CROSS APPLY.

Для оптимальной производительности я создал индекс для полей project_id (ASC) и точек (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;
0 голосов
/ 21 сентября 2011

Это должно быть то, что вы хотите, вам даже не нужно группировать или ухудшать функции:

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, затем удалите ограничение 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

Мои результаты:

Result Set (3 items)  
points | project_id | created_date 
20     | 441        | 04/02/2011 00:00:00
10     | 600        | 04/02/2011 00:00:00
15     | 241        | 21/09/2011 18:59:31
0 голосов
/ 21 сентября 2011

Я дам вам образец ..

SELECT MAX(POINTS),
       PROJECT_ID,
       CREATION_DATE 
  FROM yourtable
 GROUP by CREATION_DATE,PROJECT_ID;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...