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 19/09/2011, 16h10   #1
Invité de passage
 
Homme Xavier BLANCHARD
Ingénieur qualité méthodes
Inscription : septembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Xavier BLANCHARD
Localisation : France, Haute Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Industrie

Informations forums :
Inscription : septembre 2011
Messages : 8
Points : 1
Points : 1
Par défaut Calcul de durée par différence entre 2 enregistrements

Bonjour,

Je "débute" sur SQL server et je me retrouver confronter à un besoin assez spécifique.

Je dispose d'une table que l'on appelera "matable" comprenant les éléments suivants :
ID
DateHeure
Operateur
D'autres éléments non utiles pour le besoin actuel
Je souhaite à partir de cette table pouvoir créer une nouvelle table "nouvelletable" qui contiendrait les éléments suivants :
newID
ID
DateHeure
Duree
La table "nouvelletable" ne doit contenir que les données relative à l'opérateur 1 (ça je sais faire avec un simple WHERE).

Le champs "Duree" doit être égal à la différence entre 2 enregistrements consécutifs effectués par l'Operateur "1" dans "matable".
C'est là que je ne sais pas comment faire.

Je ne sais pas si c'est très clair donc voici un exemple d'enregistrements de "matable" et ce que je voudrais obtenir dans "nouvelletable" :

"matable"
ID / DateHeure / Operateur
1 / 2011-09-13 12:00:00,0 / 2
2 / 2011-09-13 12:05:00,0 / 1
3 / 2011-09-13 12:07:30,0 / 1
4 / 2011-09-13 12:10:00,0 / 3
5 / 2011-09-13 12:12:00,0 / 1


"nouvelletable"
newID / ID / DateHeure / Duree
1 / 2 / 2011-09-13 12:05:00,0 / 00:02:30,0
2 / 3 / 2001-09-13 12:07:30,0 / 00:04:30,0
3 / 5 / .....

J'espère avoir été assez clair.

Merci de vos lumières car là je sèche serieusement ...

Axvier
Axvier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 16h51   #2
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Comme tu dis, avec un where, tu vas déjà filtrer sur l'intervenant :
Code :
1
2
3
SELECT t1.id id1, t1.dateheure dateheure1
FROM matable t1
WHERE t1.operateur = 1;
Avec une auto-jointures et une sous-requête (ancienne syntaxe), tu pourras retrouver les heures consécutives :
Code :
1
2
3
4
5
SELECT t1.id id1, t1.dateheure dateheure1, t2.dateheure
FROM matable t1
CROSS JOIN matable t2
WHERE t1.operateur = 1
AND t2.id = (SELECT min(id) FROM matable t3 WHERE t3.id > t1.id);
Il y a plus moderne comme écriture, mais j'ai pas la syntaxe en tête et la flème de chercher.

Ensuite, t'as plus qu'à créer ta nouvelle table :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE nouvelletable
(
	newid int identity PRIMARY KEY,
	id int REFERENCES matable(id),
	dateheure datetime,
	duree datetime
);
 
INSERT INTO nouvelletable (id, dateheure, duree)
SELECT t1.id id1, t1.dateheure dateheure1, t2.dateheure - t1.dateheure durée
FROM matable t1
CROSS JOIN matable t2
WHERE t1.operateur = 1
AND t2.id = (SELECT min(id) FROM matable t3 WHERE t3.id > t1.id);
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 22h14   #3
Invité de passage
 
Homme Xavier BLANCHARD
Ingénieur qualité méthodes
Inscription : septembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Xavier BLANCHARD
Localisation : France, Haute Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Industrie

Informations forums :
Inscription : septembre 2011
Messages : 8
Points : 1
Points : 1
Merci StringBuilder,

Je teste tout ça demain au taff et annonce si c'est OK ou non.

J'avoue que pour un premier projet en SQL (malgré quelques essais mySQL précédents), là j'étais largement paumé ...

En tout cas, merci d'avance de tes lumières qui j'espère me permettrons de conclure cette satanée requête qui me pose problème depuis 15 jours !

Axv
Axvier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/09/2011, 22h39   #4
Invité de passage
 
Homme Xavier BLANCHARD
Ingénieur qualité méthodes
Inscription : septembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Xavier BLANCHARD
Localisation : France, Haute Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Industrie

Informations forums :
Inscription : septembre 2011
Messages : 8
Points : 1
Points : 1
Question complémentaire :

La table "matable" s'incrémente régulièrement donc il va falloir que j'effectue la mise à jour de la table "nouvelletable" régulièrement.

A ce jour, je me sers de Views pour interroger mes tables car j'ai juste besoin de visualisation. Les vues étant créées à chaque appel, je n'ai pas de soucis de calculs pour les afficher.

Pour la fonction demandée ci-dessus, si j'ai bien compris le fonctionnement des SGBD, il me semble préférable de créer ma table "nouvelletable" puis de créer une fonction ALTER TABLE à la place du CREATE TABLE en ajoutant une condition sur l'existance ou non du champ ID.

Merci de me dire si mon raisonnement et correct et (si ce n'est pas trop demander, me dire comment s'écrirait une telle requete).

Axv
Axvier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 09h31   #5
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Par définition, il ne faut pas stocker dans une base de données des informations calculées ou redondantes.

Donc stocker dans une table "heure de début" et "heure de fin" est redondant par rapport à "heure de début" et "durée", d'autant qu'on peut retrouver l'un part rapport à l'autre moyennant calcul.

Donc j'ai envie de te dire qu'il vaut mieux que tu crée une vue à partir de la requête que je t'ai donné : tu ne stocke pas de doublons, et du laisse les calculs là où ils sont : dans une requête, et non pas dans les données.

Cependant, en termes de performances, tu pourrais avoir rapidement des problèmes : si la volumétrie devient importante, vu la requête (qui utilise un propduit cartésien et une sous-requête avec regroupement) les temps de réponse vont vite s'allonger.

Dans ce cas, tu entres dans un cas de dénormalisation classique : il faut stocker les données.

A ce moment, deux solution s'offrent à toi :
- Si la table "matable" s'incrémente "par lot" (chargement depuis un fichier par exemple), tu peux ajouter dans le traitement par lot l'allimentation de la nouvelle table.
- Si la table "matable" s'incrémente "au fil de l'eau" (via une interface utilisateur par exemple), tu peux écrire un trigger qui va s'occuper de recopier les lignes insérrées dans la nouvelle table.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 20/09/2011, 10h06   #6
Invité de passage
 
Homme Xavier BLANCHARD
Ingénieur qualité méthodes
Inscription : septembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Xavier BLANCHARD
Localisation : France, Haute Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Industrie

Informations forums :
Inscription : septembre 2011
Messages : 8
Points : 1
Points : 1
Tout d'abord, merci pour le code, ça fonctionne à merveille



Dans le cas de cette BDD, j'ai en moyenne une nouvelle transaction toutes les 72 secondes (temps de cycle standard) et je cherche à récupérer les temps d'arrêts (d'ou le besoin d'obtenir la durée entre 2 transactions comme expliqué ci-dessus) et a pouvoir y lier un champ "commentaire" que mes techniciens maintenance pourraient renseigner lorsqu'ils interviennent.

En effet cependant, il est du coup redondant de restocker le dateheure de "matable" dans "nouvelletable", l'ID devient suffisant pour lier mes données et la "nouvelletable" me permet simplement de stocker le commentaire (et la durée accessoirement)
Axvier est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 09h10   #7
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
Localisation : France, Gironde (Aquitaine)

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

Informations forums :
Inscription : novembre 2004
Messages : 1 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
Il y a plus moderne comme écriture, mais j'ai pas la syntaxe en tête et la flème de chercher.
Ya surtout plus indenté... pensez à indenter votre code pour plus de lisibilité...

Qu'entendez vous par moderne?

Citation:
Les vues étant créées à chaque appel, je n'ai pas de soucis de calculs pour les afficher.
Vous créez vos vues avant chaque appel????
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 23/09/2011, 10h59   #8
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Citation:
Envoyé par iberserk Voir le message
Ya surtout plus indenté... pensez à indenter votre code pour plus de lisibilité...
La sous-requête étant à la fois simple et courte, je trouve plus lisible de la laisser sur une ligne, ça évite de faire des gros blocs illisible (je trouve)

Citation:
Envoyé par iberserk Voir le message
Qu'entendez vous par moderne?
On peut éviter la sous-requête avec MIN en utilisant une CTE ou une fonction analytique,je ne sais plus (j'ai envoyé il y a pas longtemps un mail aux salariés de ma boîte pour les encourager justement à utiliser l'autre syntaxe, mais je l'ai pas sous la main -changé de mission, plus accès à mes mails du boulot-, et pas envie de chercher)
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 03/10/2011, 23h04   #9
Invité de passage
 
Homme Xavier BLANCHARD
Ingénieur qualité méthodes
Inscription : septembre 2011
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Xavier BLANCHARD
Localisation : France, Haute Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur qualité méthodes
Secteur : Industrie

Informations forums :
Inscription : septembre 2011
Messages : 8
Points : 1
Points : 1
@StringBuilder :

Merci beaucoup pour ton code qui fonctionne parfaitement. Il manquait juste une condition sur l'op dans le Where (je posterai demain la requete finale)^.


@iberserk :

Non, je ne crée pas mes Vues à chaque appel, mais par principe une Vue est recalculée à chaque appel donc c'est SQL Server qui travail et non Excel dans mon cas (soit un gain de plus de 95% du temps de traitement par rapport à un appel des différentes tables sous excel et un traitement annexe des infos). Je ne suis pas encore habitué aux SGBD donc pas non plus aux terminaisons standards (comme je le précisais dans mon 1er message) ...
Axvier 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 03h21.


 
 
 
 
Partenaires

Hébergement Web