0

J'ai une table qui a 3 cols à savoir les points, project_id et creation_date. chaque fois que des points sont attribués, un nouvel enregistrement a été fait, par exemple.Groupe SQL par problème

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 est la date à laquelle enregistrement est entré et il est réalisé en définissant la valeur par défaut à getDate())

maintenant le problème est que je veux obtenir MAX Points regroupés par project_id mais je Je veux aussi que creation_date apparaisse pour que je puisse l'utiliser dans un autre but, si la date de création est répétée et que je ne peux pas grouper par creation_date car si je le fais, il passera les points du projet avec l'ID 600 et l'ID 600 est un projet différent et ses seuls points maximum sont 10 donc il devrait être listé et c'est seulement possible si je fais le grouping en utilisant project_id mais alors comment dois-je aussi lister creation_date

Jusqu'à présent, je me sers de cette requête pour obtenir des points MAX de chaque projet

SELECT MAX (points) AS points PROJECT_ID
DE LogiCpsLogs LCL
OU (writer_id = @writer_id) ET (datename (mm , GETDATE()) = DATENAME (mm, creation_date)) et (points <> 0)
GROUP BY PROJECT_ID

writer_id est l'ID de l'écrivain dont les points que je veux voir, comme writer_id = 1, 2 ou 3.

Cette requête affiche uniquement le résultat du mois en cours, mais je souhaite également lister creation_date. S'il vous plaît aider.

Répondre

2

La voie sous-requête

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 

S'il vous plaît voir le commentaire: cela vous donnera à tous les jours où les points max-a été atteint. Si vous en voulez seulement un, la requête sera plus complexe.

: Edits

  • exigences. Misread Ajout d'une contrainte supplémentaire
+1

Vous aurez également besoin d'adhérer sur les points ... sinon vous allez obtenir plus de disques que la question exige .. (ne veut que le creation_date de l'article pour chaque projet avec les points maximum). Vous devez également être attentif au cas où des points égaux (max) ont été atteints sur différents jours ... une décision devrait être prise pour travailler si vous voulez tous creation_dates où cette valeur de points a été atteint, ou si vous voulez seulement la première ou la dernière date par exemple –

+0

AH J'ai mal lu les exigences. Je pensais que la date de création était la date à laquelle le projet a été créé, pas la date de l'enregistrement. Haha! Merci pour la relecture. –

+0

Merci qui a résolu mon problème. – Ahmed

0

Je vais vous donner Maquet ..

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

Cela devrait être ce que vous voulez, vous ne même pas besoin d'un groupe par fonctions: ou aggraver

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 est votre table, aussi si vous voulez montrer seulement les enregistrements où ils étaient le total en général et non pas le total pour juste ce donné @writer_id puis supprimez la restriction T2.writer_id = @writer_id de la requête interne

Et mon code que j'utilisé pour tester:

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 

Mes résultats:

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

Mon utilisation de la solution CROSS APPLY sous-requêtes.

Pour des performances optimales, j'ai créé un index sur project_id (ASC) & points (DESC ordre de tri) des champs.

Si vous voulez voir tous les creation_date valeurs qui ont un maximum de points, vous pouvez utiliser 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;