Balayage de table unique, pas de fonction de fenêtrage, groupe unique par, pas de problèmes avec les dates en double, performances égales avec les fonctions de fenêtrage, ou même les surpasse avec de très grandes requêtes. (Mise à jour: Je ne sais pas comment il fonctionne par rapport au TOP 1 AVEC TIES/CROSS APPLY méthode Comme il utilise une analyse, il pourrait être plus lent dans certaines situations..)
SELECT
LogEntryID = Convert(int, Substring(Packed, 9, 4)),
FileID = Convert(int, Substring(Packed, 13, 4)),
CreatedOn = Convert(datetime, Substring(Packed, 1, 8)),
EventTypeID = Convert(int, Substring(Packed, 17, 4))
FROM
(
SELECT
Packed = Max(
Convert(binary(8), CreatedOn)
+ Convert(binary(4), LogEntryID)
+ Convert(binary(4), FileID)
+ Convert(binary(4), EventTypeID)
)
FROM LogEntries
WHERE EventTypeID IN (2,4)
GROUP BY ClientName
) X
Si quelqu'un aimerait voir en action, voici un script de création:
USE tempdb
CREATE TABLE LogEntries (
LogEntryID int not null identity(1,1),
FileID int,
CreatedOn datetime,
EventTypeID int,
ClientName varchar(30)
)
INSERT LogEntries VALUES (1, GetDate()-20, 2, 'bob')
INSERT LogEntries VALUES (1, GetDate()-19, 3, 'bob')
INSERT LogEntries VALUES (1, GetDate()-18, 4, 'bob')
INSERT LogEntries VALUES (1, GetDate()-17, 3, 'bob')
INSERT LogEntries VALUES (1, GetDate()-19.5, 2, 'anna')
INSERT LogEntries VALUES (1, GetDate()-18.5, 3, 'anna')
INSERT LogEntries VALUES (1, GetDate()-17.5, 4, 'anna')
INSERT LogEntries VALUES (1, GetDate()-16.5, 3, 'anna')
S'il vous plaît noter que cette méthode profite de la représentation des octets interne des types de données données ayant le même ordre que les valeurs du type. Les types de données compressés comme float ou decimal ne fonctionneront PAS: ceux qui nécessitent une conversion en quelque chose de convenable en premier, comme int, bigint ou character.
En outre, les nouveaux types de données Date et heure dans SQL 2008 ont des représentations différentes qui ne seront pas compressées correctement à utiliser avec cette méthode. Je ne l'ai pas examiné le type de données temps encore, mais pour le type de données Date:
DECLARE @d date
SET @d ='99990101'
SELECT Convert(binary(3), @d) -- 0x6EB837
La valeur réelle est 0x37B86E, il est donc de les stocker dans l'ordre des octets inverse (la date « zéro » est 0001-01- 01).
Pour toutes les personnes qui ont répondu -> je suis sincèrement sans voix (dans le bon sens) et humilié :) j'adore comment il y a un certain nombre d'approches différentes. C'est pourquoi j'aime SO. Je vais tous les vérifier et voir de quelle façon je veux peaufiner ce chat. Une fois de plus, <3 à toutes les réponses et <3 à SO :) –
Avez-vous déjà obtenu ma réponse de travail? Vous avez demandé si un schéma pourrait aider. Je vais quand même heureusement mettre à jour ma requête en réponse à certaines informations de schéma. – ErikE
non - j'ai manqué de temps sur l'exigence de travail et j'ai dû faire avec ce qui a fonctionné, etc. sincères appologies. –