Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un message
est enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du moteur
entre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un message
est enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du moteur
entre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un message
est enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du moteur
entre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto:brouardf@club-internet.fr ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto:brouardf@club-internet.fr ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:
> Bonjour à tous
>
> J'ai une Table me permettant d'historiser les états de marche et d'arrêt
> d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
> est enregistré.
>
> Id DateHeure Valeur(0=Arret;1=Marche)
> 1 18/11/2003 12:00:00 0
> 2 18/11/2003 12:45:00 1
> 3 18/11/2003 14:55:00 0
> 4 18/11/2003 15:00:00 1
> 5 19/11/2003 12:00:00 0
> 6 19/11/2003 18:00:00 1
>
> Voila la table avec des valeurs.
>
> Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
> entre deux dates.
>
> Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
> 19/11/2003 11:00:00
>
> Comment puis-je faire?
>
> Si vous avez des idées.
>
> D'avance merci et bon courage.
>
> Stef
>
>
Désolé de revenir à la charge, j'ai essayé ta requete qui marche très bien,
sauf que j'ai dans ma table des cas particuliers
Je peux avoir
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
7 18/11/2003 12:30:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
En cas de coupure de la base et de redémarrage, elle enregistre de nouveau
le point, donc je peux me retrouver avec 2 mêmes valeurs. Et là le cumul
n'est pas juste.
Autres soucis, est-ce que ça marche si je demande le temps de marche entre
deux valeurs qui ne sont pas des points enregistré, je m'explique :
- Si je fais ma requête entre 18/11/2003 12:15:30 et 18/11/2003 14:58:11
Désolée de te déranger ;-)
Merci
"Fred BROUARD" a écrit dans le message news:bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
messageest enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
moteurentre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
Désolé de revenir à la charge, j'ai essayé ta requete qui marche très bien,
sauf que j'ai dans ma table des cas particuliers
Je peux avoir
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
7 18/11/2003 12:30:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
En cas de coupure de la base et de redémarrage, elle enregistre de nouveau
le point, donc je peux me retrouver avec 2 mêmes valeurs. Et là le cumul
n'est pas juste.
Autres soucis, est-ce que ça marche si je demande le temps de marche entre
deux valeurs qui ne sont pas des points enregistré, je m'explique :
- Si je fais ma requête entre 18/11/2003 12:15:30 et 18/11/2003 14:58:11
Désolée de te déranger ;-)
Merci
"Fred BROUARD" <brouardf@club-internet.fr> a écrit dans le message news:
3FBA9102.9040508@club-internet.fr...
bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto:brouardf@club-internet.fr ******************
FAUCHILLE Stéphan a écrit:
Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
message
est enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
moteur
entre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
Désolé de revenir à la charge, j'ai essayé ta requete qui marche très bien,
sauf que j'ai dans ma table des cas particuliers
Je peux avoir
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
7 18/11/2003 12:30:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
En cas de coupure de la base et de redémarrage, elle enregistre de nouveau
le point, donc je peux me retrouver avec 2 mêmes valeurs. Et là le cumul
n'est pas juste.
Autres soucis, est-ce que ça marche si je demande le temps de marche entre
deux valeurs qui ne sont pas des points enregistré, je m'explique :
- Si je fais ma requête entre 18/11/2003 12:15:30 et 18/11/2003 14:58:11
Désolée de te déranger ;-)
Merci
"Fred BROUARD" a écrit dans le message news:bonjour
CREATE TABLE T_MOTEUR
(ID INT,
DATEHEURE DATETIME,
VALEUR BIT)
INSERT INTO T_MOTEUR VALUES (1, '18/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (2, '18/11/2003 12:45:00', 1)
INSERT INTO T_MOTEUR VALUES (3, '18/11/2003 14:55:00', 0)
INSERT INTO T_MOTEUR VALUES (4, '18/11/2003 15:00:00', 1)
INSERT INTO T_MOTEUR VALUES (5, '19/11/2003 12:00:00', 0)
INSERT INTO T_MOTEUR VALUES (6, '19/11/2003 18:00:00', 1)
1ere phase : retrouver pour chaque ligne la suivante (début et fin) :
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
DHD DHF VALEUR
------------------------- ------------------------ ------
2003-11-18 12:00:00.000 2003-11-18 12:45:00.000 0
2003-11-18 12:45:00.000 2003-11-18 14:55:00.000 1
2003-11-18 14:55:00.000 2003-11-18 15:00:00.000 0
2003-11-18 15:00:00.000 2003-11-19 12:00:00.000 1
2003-11-19 12:00:00.000 2003-11-19 18:00:00.000 0
2003-11-19 18:00:00.000 NULL 1
Cette table peut maintenant être reprise dans la clause FROM d'une
nouvelle pour calcul :
SELECT DHF - DHD AS DUREE, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE VALEUR
------------------------------------------------------ ------
1900-01-01 00:45:00.000 0
1900-01-01 02:10:00.000 1
1900-01-01 00:05:00.000 0
1900-01-01 21:00:00.000 1
1900-01-01 06:00:00.000 0
NULL 1
Mais la réponse fait apparaitres des dates au liue de temps. Pour cela
transtypons en float :
SELECT CAST(DHF - DHD AS FLOAT) AS DUREE_JOUR, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_JOUR VALEUR
----------------------------------------------------- ------
0.03125 0
9.0277777777777776E-2 1
3.4722222222222225E-3 0
0.875 1
0.25 0
NULL 1
Et pour obtenir des heures décimales :
SELECT CAST(DHF - DHD AS FLOAT) * 24 AS DUREE_H, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
DUREE_H VALEUR
----------------------------------------------------- ------
0.75 0
2.1666666666666665 1
8.3333333333333343E-2 0
21.0 1
6.0 0
NULL 1
En ajoutant cette fonction, nous avons les heures décimales converties
en HMS :
CREATE FUNCTION FN_CONVERT_HD_HMS (@HD FLOAT)
RETURNS VARCHAR(8)
AS
BEGIN
DECLARE @H INTEGER
DECLARE @M INTEGER
DECLARE @S INTEGER
DECLARE @RETVAL VARCHAR(8)
-- cas trivial
IF @HD IS NULL
RETURN NULL
-- récupération des heures, minutes, secondes
SET @H = FLOOR(@HD)
SET @HD = @HD - @H
SET @HD = @HD * 60
SET @M = FLOOR(@HD)
SET @HD = @HD - @M
SET @HD = @HD * 60
SET @S = FLOOR(@HD)
IF @H < 10
SET @RETVAL = '0'+CAST(@H AS CHAR(1))+':'
ELSE
SET @RETVAL = CAST(@H AS CHAR(2))+':'
IF @M < 10
SET @RETVAL = @RETVAL + '0' + CAST(@M AS CHAR(1))+':'
ELSE
SET @RETVAL = @RETVAL + CAST(@M AS CHAR(2))+':'
IF @S < 10
SET @RETVAL = @RETVAL + '0' + CAST(@S AS CHAR(1))
ELSE
SET @RETVAL = @RETVAL + CAST(@S AS CHAR(2))+':'
RETURN @RETVAL
END
La requête avec la fonction :
SELECT dbo.FN_CONVERT_HD_HMS (CAST(DHF - DHD AS FLOAT) * 24)
AS DUREE_HMS, VALEUR
FROM
(
SELECT DATEHEURE DHD, (SELECT MIN(DATEHEURE)
FROM T_MOTEUR T2
WHERE T2.DATEHEURE > T1.DATEHEURE
AND T2.VALEUR <> T1.VALEUR
GROUP BY T2.VALEUR) DHF, VALEUR
FROM T_MOTEUR T1
) TT
Le résultat :
DUREE_HMS VALEUR
---------- ------
00:45:00 0
02:09:59 1
00:05:00 0
21:00:00 1
06:00:00 0
NULL 1
etc...
Libre à toi après de faire un cumul (SUM) entre deux datetime (BETWEEN)
passées en paramètres...
A +
--
Frédéric BROUARD - expert SQL, spécialiste : SQL Server / Delphi / web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
****************** mailto: ******************
FAUCHILLE Stéphan a écrit:Bonjour à tous
J'ai une Table me permettant d'historiser les états de marche et d'arrêt
d'un moteur. A chaque fois qu'il se met en marche ou s'arrête, un
messageest enregistré.
Id DateHeure Valeur(0=Arret;1=Marche)
1 18/11/2003 12:00:00 0
2 18/11/2003 12:45:00 1
3 18/11/2003 14:55:00 0
4 18/11/2003 15:00:00 1
5 19/11/2003 12:00:00 0
6 19/11/2003 18:00:00 1
Voila la table avec des valeurs.
Maintenant je souhaite connaitre le temps de marche (ou d'arrêt) du
moteurentre deux dates.
Par exemple le temps de marche du moteur entre le 18/11/2003 12:10:00 et
19/11/2003 11:00:00
Comment puis-je faire?
Si vous avez des idées.
D'avance merci et bon courage.
Stef
Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
seule requête. Mais bon.
Encore merci à toi.
Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
seule requête. Mais bon.
Encore merci à toi.
Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
seule requête. Mais bon.
Encore merci à toi.
En une seule requête oui, il suffit d'encapsuler les vues au sein des
from...
Mais les vues ont l'avantage d'une plus grande lisibilité et peuvent
être indexées...
A +
FAUCHILLE Stéphan a écrit :
> Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
> seule requête. Mais bon.
>
> Encore merci à toi.
>
>
>
>
En une seule requête oui, il suffit d'encapsuler les vues au sein des
from...
Mais les vues ont l'avantage d'une plus grande lisibilité et peuvent
être indexées...
A +
FAUCHILLE Stéphan a écrit :
> Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
> seule requête. Mais bon.
>
> Encore merci à toi.
>
>
>
>
En une seule requête oui, il suffit d'encapsuler les vues au sein des
from...
Mais les vues ont l'avantage d'une plus grande lisibilité et peuvent
être indexées...
A +
FAUCHILLE Stéphan a écrit :
> Ca marche mais ça commence à faire gros. Je pensais cela faisable en une
> seule requête. Mais bon.
>
> Encore merci à toi.
>
>
>
>