sql sum group by multiple columns




Comment puis-je inclure des valeurs nulles dans un MIN ou un MAX? (5)

C’est un peu moche, mais comme la NULL a une signification particulière pour vous, c’est la façon la plus propre de le faire:

SELECT recordid, MIN(startdate),
   CASE WHEN MAX(CASE WHEN enddate IS NULL THEN 1 ELSE 0 END) = 0
        THEN MAX(enddate)
   END
FROM tmp GROUP BY recordid

C'est-à-dire que si une ligne a une NULL , nous voulons forcer cette réponse. MIN le MIN (ou MAX ) uniquement si aucune ligne ne contient un NULL .

J'ai une table où je stocke des données de durée. la table a un schéma similaire à:

ID INT NOT NULL IDENTITY(1,1)   
RecordID INT NOT NULL  
StartDate DATE NOT NULL  
EndDate DATE NULL  

Et j'essaie de déterminer les dates de début et de fin de chaque ID d'enregistrement, donc les dates minimales StartDate et EndDate maximales. StartDate n'est pas nullable, donc je n'ai pas à m'inquiéter à ce sujet, mais j'ai besoin de MAX (EndDate) pour indiquer qu'il s'agit actuellement d'une durée d'exécution.

Il est important que je maintienne la valeur NULL de EndDate et que je la traite comme la valeur maximale.

La tentative la plus simple (ci-dessous) ne fonctionne pas, soulignant le problème selon lequel MIN et MAX ignoreront NULLS (source: http://technet.microsoft.com/en-us/library/ms179916.aspx ).

SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid

J'ai créé un SQL Fiddle avec la configuration de base effectuée.

http://sqlfiddle.com/#!3/b0a75

Comment puis-je plier SQL Server 2008 à ma volonté pour produire le résultat suivant à partir des données fournies dans SQLFiddle?

RecordId  Start       End  
1         2009-06-19  NULL
2         2012-05-06  NULL
3         2013-01-25  NULL
4         2004-05-06  2009-12-01

En supposant que vous n'ayez qu'un seul enregistrement avec null dans la colonne EndDate pour un RecordID donné, quelque chose comme ceci devrait vous donner le résultat souhaité:

WITH cte1 AS
(
SELECT recordid, MIN(startdate) as min_start , MAX(enddate) as max_end
FROM tmp 
GROUP BY recordid
)

SELECT a.recordid, a.min_start , 
CASE 
   WHEN b.recordid IS  NULL THEN a.max_end
END as max_end
FROM cte1 a
LEFT JOIN tmp b ON (b.recordid = a.recordid AND b.enddate IS NULL)

L’effet souhaité est de traiter la valeur NULL comme la date la plus grande possible, puis de la remplacer par NULL à la fin:

SELECT RecordId, MIN(StartDate), NULLIF(MAX(COALESCE(EndDate,'9999-12-31')),'9999-12-31') 
  FROM tmp GROUP BY RecordId

Selon votre violon, cela retournera les résultats exacts que vous spécifiez dans toutes les conditions.


Utilisez IsNull

SELECT recordid, MIN(startdate), MAX(IsNull(enddate, Getdate()))
FROM tmp 
GROUP BY recordid

J'ai modifié MIN dans la deuxième instruction en MAX


in my expression - count (enddate) compte le nombre de lignes dont la date de fin n'est pas nulle. count (*) compte le nombre de lignes total. En comparant, vous pouvez facilement déterminer si une date de fin contient null. Si elles sont identiques, alors max (enddate) est le résultat. Sinon, le cas par défaut renverra null qui est aussi la réponse. C'est un moyen très populaire de faire cette vérification exacte.

SELECT recordid, 
MIN(startdate), 
case when count(enddate) = count(*) then max(enddate) end
FROM tmp 
GROUP BY recordid




tsql