Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 16/02/2011, 14h30   #1
Membre Expert
 
Inscription : janvier 2006
Messages : 1 111
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 1 111
Points : 1 093
Points : 1 093
Par défaut Agrégation des données par demi-heure

Bonjour,

J'ai des données (beaucoup) avec un champ datetime.
Je souhaiterais regrouper mes données par 1/2 heure (ou 1/4 heure).
Je travaille sur SQL Server 2008.

Comment puis-je m'y prendre ?

Merci.
__________________
[Access] Les bases du débogage => ici
Kloun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 15h31   #2
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 950
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 950
Points : 17 769
Points : 17 769
Créez une table de chronodatage au pas voulu.
Faites une jointure externe droite avec cette table
Groupez par la chronodatation.

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 15h55   #3
Membre Expert
 
Inscription : janvier 2006
Messages : 1 111
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 1 111
Points : 1 093
Points : 1 093
Merci pour la réponse
Citation:
Envoyé par SQLpro Voir le message
Créez une table de chronodatage au pas voulu.
SI je comprends bien, une table avec une colonne dans laquelle je retrouve mes 1/2 heures ou 1/4 heures :
05:00:00
05:30:00
06:00:00
06:15:00
06:30:00

Citation:
Envoyé par SQLpro Voir le message
Faites une jointure externe droite avec cette table
Là, j'ai plus de mal...
Mes données sont du genre :
17:12:45
14:33:53
06:01:21
Comment puis-je faire ma jointure ?

Citation:
Envoyé par SQLpro Voir le message
Groupez par la chronodatation.
Ça, ça ne devrait pas poser de problème.
__________________
[Access] Les bases du débogage => ici
Kloun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 16h08   #4
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Vous pouvez vous inspirer de ceci :

Code sql :
1
2
3
4
5
6
7
8
9
10
11
12
13
 
WITH Ref AS(
	SELECT CAST('2010-01-01 00:00' AS DATETIME) AS debut, DATEADD(MINUTE, 15, '2011-01-01 00:00') AS Fin
	UNION ALL
	SELECT Fin, DATEADD(MINUTE, 15, Fin)
	FROM Ref
	WHERE Fin < '2011-10-01 00:00'
)
SELECT *
FROM Ref
INNER JOIN MaTable ON MaColonneDate >= debut 
    AND MaColonneDate < fin
OPTION (MAXRECURSION 0)

pour les dates de la CTE, spécifiez les bornes de debut et fin correctes (en allant les chercher dans votre table source par exemple...)
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 16h16   #5
Membre Expert
 
Inscription : janvier 2006
Messages : 1 111
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 1 111
Points : 1 093
Points : 1 093
Au temps pour moi, j'avais pas pensé à la jointure
Code :
1
2
MaColonneDate >= debut 
    AND MaColonneDate < fin
A partir de là, c'est tout simple ...

Merci.
__________________
[Access] Les bases du débogage => ici
Kloun est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 18h05   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 950
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 950
Points : 17 769
Points : 17 769
Il vaut mieux créer la table en dur que la faire par récursion via CTE;.. Notre thaïlandais ayant tendance à faire trop de requêtes récursives....
Sans doute l'influence de boudha, des sourires des thaïlandaises et de la cuisine trop épicée !!!

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 21h09   #7
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 667
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 667
Points : 8 715
Points : 8 715
Alors là je ne vois vraiment pas de qui tu veux parler ...
Trop de requêtes récursives ... bon OK, c'est vrai, j'ai usé et même abusé des CTE, mais c'est tellement pratique ...

Bon par contre la récursivité j'en suis revenu, et j'aurai préconisé la même solution que celle que tu as proposée, en me basant sur mon article sur la table de dates

Pour faire brutal j'aurai donc peuplé une table avec la requête utilisant une CTE récursive (peux pas m'en passer, désolé) ou bien une requête WHILE ...
La suite :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
CREATE TABLE tb_subdivision_temps
(
	subdivision_temps_id tinyint IDENTITY NOT NULL CONSTRAINT PKtb_subdivision_temps PRIMARY KEY
	, subdivision_temps_nom varchar(32) NOT NULL CONSTRAINT UQtb_subdivision_temps__subdivision_temps_nom UNIQUE (subdivision_temps_nom)
	, nombre_minutes tinyint NOT NULL CONSTRAINT CHKtb_subdivision_temps__nombre_minutes CHECK(nombre_minutes IN (0, 5, 10, 15, 30, 45))
)
GO
 
CREATE TABLE tb_date
(
	date_id int IDENTITY NOT NULL CONSTRAINT PKtb_date PRIMARY KEY
	, date_heure datetime NOT NULL CONSTRAINT UQtb_date__date_heure UNIQUE (date_heure)
	, subdivision_temps_id tinyint CONSTRAINT FKtb_date__subdivision_temps_id FOREIGN KEY (subdivision_temps_id) REFERENCES dbo.tb_subdivision_temps
	, date_heure_plus_15_min AS(DATEADD(minute, 15, date_heure))
	, date_heure_plus_30_min AS(DATEADD(minute, 30, date_heure))
)
GO
 
CREATE INDEX IXtb_date__date_heure__date_heure_plus_15_min
ON dbo.tb_date(date_heure, date_heure_plus_15_min, subdivision_temps_id)
GO
 
CREATE INDEX IXtb_date__date_heure__date_heure_plus_30_min
ON dbo.tb_date(date_heure, date_heure_plus_30_min, subdivision_temps_id)
GO
 
INSERT	INTO dbo.tb_subdivision_temps (subdivision_temps_nom, nombre_minutes)
VALUES	('cinq minutes', 5)
	, ('dix minutes', 10)
	, ('un quart d''heure', 15)
	, ('une demi-heure', 30)
	, ('trois quarts d''heure', 45)
	, ('une heure', 0)
GO
 
ALTER TABLE dbo.tb_date
ADD CONSTRAINT DFtb_date__subdivision_temps_id
	DEFAULT (1) FOR subdivision_temps_id
GO
 
SET NOCOUNT ON
GO
 
DECLARE @date_deb datetime = '20100101'
WHILE @date_deb < CAST('20120101' AS datetime)
BEGIN
	INSERT	INTO dbo.tb_date(date_heure)
	SELECT	@date_deb
 
	SELECT	@date_deb = DATEADD(minute, 5, @date_deb)
END
 
SET NOCOUNT OFF
GO
 
UPDATE		dbo.tb_date
SET		subdivision_temps_id = ST.subdivision_temps_id
FROM		dbo.tb_date AS D
INNER JOIN	dbo.tb_subdivision_temps AS ST
			ON DATEPART(minute, D.date_heure) = ST.nombre_minutes
GO
Et on peut donc écrire une requête du style :

Code :
1
2
3
4
5
6
7
8
9
SELECT		T.*
		, D.date_heure
FROM		dbo.maTable AS T
INNER JOIN	dbo.tb_date AS D
			ON T.MaColonneDate >= D.date_heure
			AND T.MaColonneDate < D.date_heure_plus_15_min
INNER JOIN	dbo.tb_subdivision_temps AS ST
			ON D.subdivision_temps_id = ST.subdivision_temps_id
WHERE		ST.nombre_minutes IN (0, 15, 30, 45)
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/02/2011, 09h00   #8
Membre Expert
 
Inscription : janvier 2006
Messages : 1 111
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 1 111
Points : 1 093
Points : 1 093
J'ai effectivement créé une table de période avec HeureDebut et HeureFin pour subdiviser la journée.
Avec une interface pour que l'utilisateur puisse gérer ses périodes comme il l'entend (période de 1h en début de journée, 1/2 heure dans la matinée, 1/4 heure ensuite ...), ça va nickel.
__________________
[Access] Les bases du débogage => ici
Kloun est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h51.


 
 
 
 
Partenaires

Hébergement Web