Problème de requete optimisée

Le
jerome
Bonjour,

J'ai un problème pour faire et optimiser une requete.

Pour simplifier, j'ai une table mouvement avec
mouv_date datetime
mouv_type int
mouv_valeur decimal(18,2)

avec mouv_date = date du mouvement
mouv_type = type du mouvement : 1 et 2 = achats ; 3 et 4 = ventes
mouv_valeur = valeur

En entrant en paramètres une date de départ et une date de fin je
souhaiterais obtenir un résultat de ce type

mois achats n-1 achat n ventes n-1 ventes n

Donc obtenir, par exemple si l'on entre comme paramètres @debut='01/01/2009'
et @fin ='31/03/2009'
quelque chose du style

janvier (ou 1) a1-1 a1 v1-1 v1
février (ou 2) a2-1 a2 v2-1 v2
février (ou 1) a3-1 a 3 v3-1 v3

Pour l'instant je fais de multiples requêtes pour chaque valeur et ça ne me
semble pas terrible terrible.

Merci par avance
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fred BROUARD
Le #20352611
CREATE table mouvement (
mouv_date datetime,
mouv_type int,
mouv_valeur decimal(18,2))

INSERT INTO mouvement VALUES ('1/1/2009', 1, 123)
INSERT INTO mouvement VALUES ('10/1/2009', 2, 456)
INSERT INTO mouvement VALUES ('15/1/2009', 3, 789)
INSERT INTO mouvement VALUES ('1/2/2009', 4, 147)
INSERT INTO mouvement VALUES ('10/3/2009', 1, 258)

WITH T AS
(
SELECT YEAR(mouv_date) AS AN, MONTH(mouv_date) AS MOIS,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN mouv_valeur
WHEN mouv_type IN (3, 4) THEN 0
END) AS TOTAL_ACHAT,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN 0
WHEN mouv_type IN (3, 4) THEN mouv_valeur
END) AS TOTAL_VENTE
FROM mouvement
GROUP BY YEAR(mouv_date), MONTH(mouv_date)
)
SELECT T1.AN, T1.MOIS,
T1.TOTAL_ACHAT AS TOTAL_ACHAT_PRED,
T2.TOTAL_ACHAT AS TOTAL_ACHAT_ACTU,
T1.TOTAL_VENTE AS TOTAL_VENTE_PRED,
T2.TOTAL_VENTE AS TOTAL_VENTE_ACTU
FROM T AS T1
LEFT OUTER JOIN T AS T2
ON T1.AN * 12 + T1.MOIS = T2.AN * 12 + T2.MOIS - 1
ORDER BY AN, MOIS


AN MOIS TOTAL_ACHAT_PRED TOTAL_ACHAT_ACTU TOTAL_VENTE_PRED
TOTAL_VENTE_ACTU
----- ----- ----------------- ---------------- ----------------
----------------
2009 1 579.00 0.00 789.00 147.00
2009 2 0.00 258.00 147.00 0.00
2009 3 258.00 NULL 0.00 NULL

Et pour apprendre le SQL, mon site comme mes bouquins, sont là pour ça !


A +



--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
Enseignant aux Arts & Métiers PACA et à L'ISEN Toulon - Var Technologies
*********************** http://www.sqlspot.com *************************


jerome a écrit :
Bonjour,

J'ai un problème pour faire et optimiser une requete.

Pour simplifier, j'ai une table mouvement avec
mouv_date datetime
mouv_type int
mouv_valeur decimal(18,2)

avec mouv_date = date du mouvement
mouv_type = type du mouvement : 1 et 2 = achats ; 3 et 4 = ventes
mouv_valeur = valeur

En entrant en paramètres une date de départ et une date de fin je
souhaiterais obtenir un résultat de ce type

mois achats n-1 achat n ventes n-1 ventes n

Donc obtenir, par exemple si l'on entre comme paramètres @debut='01/01/2009'
et @fin ='31/03/2009'
quelque chose du style

janvier (ou 1) a1-1 a1 v1-1 v1
février (ou 2) a2-1 a2 v2-1 v2
février (ou 1) a3-1 a 3 v3-1 v3

Pour l'instant je fais de multiples requêtes pour chaque valeur et ça ne me
semble pas terrible terrible.

Merci par avance





jerome
Le #20352891
Merci beaucoup Fred,

Je vais souvent sur votre site pour chercher des infos.
Pour ce qui est des bouquins, avec Internet, pour la recherche
d'informations techniques, on lit moins globalement et plus parcellairement
(enfin moi).

Merci encore

"Fred BROUARD" news:
CREATE table mouvement (
mouv_date datetime,
mouv_type int,
mouv_valeur decimal(18,2))

INSERT INTO mouvement VALUES ('1/1/2009', 1, 123)
INSERT INTO mouvement VALUES ('10/1/2009', 2, 456)
INSERT INTO mouvement VALUES ('15/1/2009', 3, 789)
INSERT INTO mouvement VALUES ('1/2/2009', 4, 147)
INSERT INTO mouvement VALUES ('10/3/2009', 1, 258)

WITH T AS
(
SELECT YEAR(mouv_date) AS AN, MONTH(mouv_date) AS MOIS,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN mouv_valeur
WHEN mouv_type IN (3, 4) THEN 0
END) AS TOTAL_ACHAT,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN 0
WHEN mouv_type IN (3, 4) THEN mouv_valeur
END) AS TOTAL_VENTE
FROM mouvement
GROUP BY YEAR(mouv_date), MONTH(mouv_date)
)
SELECT T1.AN, T1.MOIS,
T1.TOTAL_ACHAT AS TOTAL_ACHAT_PRED,
T2.TOTAL_ACHAT AS TOTAL_ACHAT_ACTU,
T1.TOTAL_VENTE AS TOTAL_VENTE_PRED,
T2.TOTAL_VENTE AS TOTAL_VENTE_ACTU
FROM T AS T1
LEFT OUTER JOIN T AS T2
ON T1.AN * 12 + T1.MOIS = T2.AN * 12 + T2.MOIS - 1
ORDER BY AN, MOIS


AN MOIS TOTAL_ACHAT_PRED TOTAL_ACHAT_ACTU TOTAL_VENTE_PRED
TOTAL_VENTE_ACTU
----- ----- ----------------- ---------------- ----------------
----------------
2009 1 579.00 0.00 789.00 147.00
2009 2 0.00 258.00 147.00 0.00
2009 3 258.00 NULL 0.00 NULL

Et pour apprendre le SQL, mon site comme mes bouquins, sont là pour ça !


A +



--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
Enseignant aux Arts & Métiers PACA et à L'ISEN Toulon - Var Technologies
*********************** http://www.sqlspot.com *************************


jerome a écrit :
> Bonjour,
>
> J'ai un problème pour faire et optimiser une requete.
>
> Pour simplifier, j'ai une table mouvement avec
> mouv_date datetime
> mouv_type int
> mouv_valeur decimal(18,2)
>
> avec mouv_date = date du mouvement
> mouv_type = type du mouvement : 1 et 2 = achats ; 3 et 4 = ventes
> mouv_valeur = valeur
>
> En entrant en paramètres une date de départ et une date de fin je
> souhaiterais obtenir un résultat de ce type
>
> mois achats n-1 achat n ventes n-1 ventes n
>
> Donc obtenir, par exemple si l'on entre comme paramètres


@debut='01/01/2009'
> et @fin ='31/03/2009'
> quelque chose du style
>
> janvier (ou 1) a1-1 a1 v1-1 v1
> février (ou 2) a2-1 a2 v2-1 v2
> février (ou 1) a3-1 a 3 v3-1 v3
>
> Pour l'instant je fais de multiples requêtes pour chaque valeur et ça ne


me
> semble pas terrible terrible.
>
> Merci par avance
>
>
>



jerome
Le #20353571
Re bonjour Fred,

J'ai essayé d'implémenter cela chez moi et en fait ce n'est pas exactement
ce que je recherche
Si j'ajoute une ligne
INSERT INTO mouvement VALUES ('1/1/2008', 1, 123)

J'obtiens le résultat suivant
2008 1 123.00 NULL 0.00 NULL
2009 1 579.00 0.00 789.00 147.00
2009 2 0.00 258.00 147.00 0.00
2009 3 258.00 NULL 0.00 NULL

Mais en fait dans total_achat_pred j'ai les achats du mois de l'année en
cours et dans total_achat _actu j'ai les achats du mois suivant.
Idem pour les ventes.
Ce que je cherche à avoir c'est dans total_achat_pred les achats du mois de
l'année n-1 et dans total_achat _actu les achats du mois en cours

Ce qui donnerait avec les données qu'il y a
2009 1 123 579 NULL 789
2009 2 NULL 0 NULL 147
2009 3 NULL 258 NULL 0

La référence de base se faisant sur l'année en cours.

Je vais essayer de voir avec la jointure externe et d 'éliminer l'année 2008
du jeu de résultats.

Ca fait mal au crâne de bon matin...

Merci



"Fred BROUARD" news:
CREATE table mouvement (
mouv_date datetime,
mouv_type int,
mouv_valeur decimal(18,2))

INSERT INTO mouvement VALUES ('1/1/2009', 1, 123)
INSERT INTO mouvement VALUES ('10/1/2009', 2, 456)
INSERT INTO mouvement VALUES ('15/1/2009', 3, 789)
INSERT INTO mouvement VALUES ('1/2/2009', 4, 147)
INSERT INTO mouvement VALUES ('10/3/2009', 1, 258)

WITH T AS
(
SELECT YEAR(mouv_date) AS AN, MONTH(mouv_date) AS MOIS,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN mouv_valeur
WHEN mouv_type IN (3, 4) THEN 0
END) AS TOTAL_ACHAT,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN 0
WHEN mouv_type IN (3, 4) THEN mouv_valeur
END) AS TOTAL_VENTE
FROM mouvement
GROUP BY YEAR(mouv_date), MONTH(mouv_date)
)
SELECT T1.AN, T1.MOIS,
T1.TOTAL_ACHAT AS TOTAL_ACHAT_PRED,
T2.TOTAL_ACHAT AS TOTAL_ACHAT_ACTU,
T1.TOTAL_VENTE AS TOTAL_VENTE_PRED,
T2.TOTAL_VENTE AS TOTAL_VENTE_ACTU
FROM T AS T1
LEFT OUTER JOIN T AS T2
ON T1.AN * 12 + T1.MOIS = T2.AN * 12 + T2.MOIS - 1
ORDER BY AN, MOIS


AN MOIS TOTAL_ACHAT_PRED TOTAL_ACHAT_ACTU TOTAL_VENTE_PRED
TOTAL_VENTE_ACTU
----- ----- ----------------- ---------------- ----------------
----------------
2009 1 579.00 0.00 789.00 147.00
2009 2 0.00 258.00 147.00 0.00
2009 3 258.00 NULL 0.00 NULL

Et pour apprendre le SQL, mon site comme mes bouquins, sont là pour ça !


A +



--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
Enseignant aux Arts & Métiers PACA et à L'ISEN Toulon - Var Technologies
*********************** http://www.sqlspot.com *************************


jerome a écrit :
> Bonjour,
>
> J'ai un problème pour faire et optimiser une requete.
>
> Pour simplifier, j'ai une table mouvement avec
> mouv_date datetime
> mouv_type int
> mouv_valeur decimal(18,2)
>
> avec mouv_date = date du mouvement
> mouv_type = type du mouvement : 1 et 2 = achats ; 3 et 4 = ventes
> mouv_valeur = valeur
>
> En entrant en paramètres une date de départ et une date de fin je
> souhaiterais obtenir un résultat de ce type
>
> mois achats n-1 achat n ventes n-1 ventes n
>
> Donc obtenir, par exemple si l'on entre comme paramètres


@debut='01/01/2009'
> et @fin ='31/03/2009'
> quelque chose du style
>
> janvier (ou 1) a1-1 a1 v1-1 v1
> février (ou 2) a2-1 a2 v2-1 v2
> février (ou 1) a3-1 a 3 v3-1 v3
>
> Pour l'instant je fais de multiples requêtes pour chaque valeur et ça ne


me
> semble pas terrible terrible.
>
> Merci par avance
>
>
>



jerome
Le #20353701
Merci j'ai fini par trouver

SELECT T1.AN, T1.MOIS,
T1.TOTAL_ACHAT AS TOTAL_ACHAT,
T2.TOTAL_ACHAT AS TOTAL_ACHAT_PREC,
T1.TOTAL_VENTE AS TOTAL_VENTE,
T2.TOTAL_VENTE AS TOTAL_VENTE_PREC
FROM T AS T1
LEFT OUTER JOIN T AS T2
ON T1.AN-1 = T2.AN and T2.MOIS =T1.MOIS
WHERE T1.AN = YEAR(getdate())
ORDER BY AN, MOIS

Merci encore


"Fred BROUARD" news:
CREATE table mouvement (
mouv_date datetime,
mouv_type int,
mouv_valeur decimal(18,2))

INSERT INTO mouvement VALUES ('1/1/2009', 1, 123)
INSERT INTO mouvement VALUES ('10/1/2009', 2, 456)
INSERT INTO mouvement VALUES ('15/1/2009', 3, 789)
INSERT INTO mouvement VALUES ('1/2/2009', 4, 147)
INSERT INTO mouvement VALUES ('10/3/2009', 1, 258)

WITH T AS
(
SELECT YEAR(mouv_date) AS AN, MONTH(mouv_date) AS MOIS,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN mouv_valeur
WHEN mouv_type IN (3, 4) THEN 0
END) AS TOTAL_ACHAT,
SUM(CASE
WHEN mouv_type IN (1, 2) THEN 0
WHEN mouv_type IN (3, 4) THEN mouv_valeur
END) AS TOTAL_VENTE
FROM mouvement
GROUP BY YEAR(mouv_date), MONTH(mouv_date)
)
SELECT T1.AN, T1.MOIS,
T1.TOTAL_ACHAT AS TOTAL_ACHAT_PRED,
T2.TOTAL_ACHAT AS TOTAL_ACHAT_ACTU,
T1.TOTAL_VENTE AS TOTAL_VENTE_PRED,
T2.TOTAL_VENTE AS TOTAL_VENTE_ACTU
FROM T AS T1
LEFT OUTER JOIN T AS T2
ON T1.AN * 12 + T1.MOIS = T2.AN * 12 + T2.MOIS - 1
ORDER BY AN, MOIS


AN MOIS TOTAL_ACHAT_PRED TOTAL_ACHAT_ACTU TOTAL_VENTE_PRED
TOTAL_VENTE_ACTU
----- ----- ----------------- ---------------- ----------------
----------------
2009 1 579.00 0.00 789.00 147.00
2009 2 0.00 258.00 147.00 0.00
2009 3 258.00 NULL 0.00 NULL

Et pour apprendre le SQL, mon site comme mes bouquins, sont là pour ça !


A +



--
Frédéric BROUARD, MVP SQL Server, expert bases de données et langage SQL
Le site sur le langage SQL et les SGBDR : http://sqlpro.developpez.com
Audit, conseil, expertise, formation, modélisation, tuning, optimisation
Enseignant aux Arts & Métiers PACA et à L'ISEN Toulon - Var Technologies
*********************** http://www.sqlspot.com *************************


jerome a écrit :
> Bonjour,
>
> J'ai un problème pour faire et optimiser une requete.
>
> Pour simplifier, j'ai une table mouvement avec
> mouv_date datetime
> mouv_type int
> mouv_valeur decimal(18,2)
>
> avec mouv_date = date du mouvement
> mouv_type = type du mouvement : 1 et 2 = achats ; 3 et 4 = ventes
> mouv_valeur = valeur
>
> En entrant en paramètres une date de départ et une date de fin je
> souhaiterais obtenir un résultat de ce type
>
> mois achats n-1 achat n ventes n-1 ventes n
>
> Donc obtenir, par exemple si l'on entre comme paramètres


@debut='01/01/2009'
> et @fin ='31/03/2009'
> quelque chose du style
>
> janvier (ou 1) a1-1 a1 v1-1 v1
> février (ou 2) a2-1 a2 v2-1 v2
> février (ou 1) a3-1 a 3 v3-1 v3
>
> Pour l'instant je fais de multiples requêtes pour chaque valeur et ça ne


me
> semble pas terrible terrible.
>
> Merci par avance
>
>
>



Publicité
Poster une réponse
Anonyme