Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Problème de requete optimisée

4 réponses
Avatar
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

4 réponses

Avatar
Fred BROUARD
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





Avatar
jerome
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" wrote in message
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
>
>
>



Avatar
jerome
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" wrote in message
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
>
>
>



Avatar
jerome
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" wrote in message
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
>
>
>