OVH Cloud OVH Cloud

SELECT complexe (ou impossible ?)

3 réponses
Avatar
OokieDookie
Bonjour à tous,

Je suis confronté à une difficulté que je n'arrive pas à contourner avec une
syntaxe SELECT :

- Soit T_SAL la table des salariés
Matricule CompteurSal Nom Prénom
00001 1 DUPONT Pierre
00543 2 DURAND Etienne
...

- Soit T_HST_CONTRAT la table des contrats de travail :
Id CompteurSal DateHist TypeContrat InfoEnCours
1 1 02/01/06 CDD 0
2 1 02/05/06 CDI 1
...

- Soit T_HAFF la table des bulletins de salaires
Id Date CompteurSal
1 31/01/06 1
2 28/02/06 1
3 31/03/06 1
4 30/04/06 1
5 31/05/06 1
...

Je voudrais obtenir dans une seule grille les données de T_SAL et T_HAFF,
avec le TypeContrat de T_HST_CONTRAT, soit pour le 1er salarié :

Matricule Nom Prénom DateHist Type
00001 DURAND Pierre 31/01/06 CDD
00001 DURAND Pierre 28/02/06 CDD
00001 DURAND Pierre 31/03/06 CDI
00001 DURAND Pierre 30/04/06 CDI
00001 DURAND Pierre 31/05/06 CDI

Or en fonctionnant avec des jointures "classiques", je récupère des
résultats qui visiblement relèvent du produit cartésien :(

Je ne sais pas s'il est possible d'indiquer dans une instruction SELECT que
la valeur à prendre est la date écoulée la plus proche (par exemple en
février récupérer le 02/01). De plus je ne peux pas altérer le modèle de
données...

Je cherche vraiment, si cela est possible, et même au détriment des
performances, à passer par un SELECT. Sinon je pense que créer une autre
table et insérer un trigger sur la table T_HAFF (référence du traitement)
sera possible, mais je voudrais éviter cela.

Pouvez-vous m'orienter ? D'avance merci et bonne journée.

3 réponses

Avatar
Christophe
essaye ça !
pas sur de ce que tu demandes mais bon si ca peut t'aider !



create table #T_SAL (Matricule varchar(10), CompteurSal int, Nom
varchar(50), Prenom varchar(50))
create table #T_HST (id int identity (1,1), CompteurSal int , DateHist
datetime, TypeContrat varchar(10), InfoEnCours tinyint default (0))
create table #T_HAFF (id int identity (1,1), CompteurSal int , DDate
datetime)

insert into #t_SAL (matricule, compteurSal, Nom, prenom)
values ('00001', 1, 'Dupont', 'Pierre')
insert into #t_SAL (matricule, compteurSal, Nom, prenom)
values ('00543', 2, 'Dupont', 'Etienne')

insert into #T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (1, '02/01/05', 'cdd',0)
insert into #T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (1, '02/05/05', 'cdi',1)
insert into #T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (2, '02/05/05', 'cdi',1)

insert into #T_HAFF (compteurSal, ddate)
values (1, '30/03/05')
insert into #T_HAFF (compteurSal, ddate)
values (1, '30/04/05')
insert into #T_HAFF (compteurSal, ddate)
values (1, '30/05/05')
insert into #T_HAFF (compteurSal, ddate)
values (1, '30/06/05')
insert into #T_HAFF (compteurSal, ddate)
values (1, '30/07/05')
insert into #T_HAFF (compteurSal, ddate)
values (2, '30/06/05')
insert into #T_HAFF (compteurSal, ddate)
values (2, '30/07/05')


select * from #t_SAL
select * from #T_HST
select * from #T_HAFF

select TS.matricule, ts.nom, TS.prenom, haff.ddate as Date_Salaire
,(select top 1 typecontrat from #T_HST where compteursal = ts.compteursal
and datehist < HAFF.ddate order by datehist desc) as TypeContrat
from #T_SAL as TS
inner join #T_HAFF as HAFF on ts.compteurSal = HAFF.compteurSal
order by haff.ddate


/*
drop table #t_sal
drop table #T_HST
drop table #T_HAFF
*/


"OokieDookie" a écrit dans le message de
news:
Bonjour à tous,

Je suis confronté à une difficulté que je n'arrive pas à contourner avec


une
syntaxe SELECT :

- Soit T_SAL la table des salariés
Matricule CompteurSal Nom Prénom
00001 1 DUPONT Pierre
00543 2 DURAND Etienne
...

- Soit T_HST_CONTRAT la table des contrats de travail :
Id CompteurSal DateHist TypeContrat InfoEnCours
1 1 02/01/06 CDD 0
2 1 02/05/06 CDI 1
...

- Soit T_HAFF la table des bulletins de salaires
Id Date CompteurSal
1 31/01/06 1
2 28/02/06 1
3 31/03/06 1
4 30/04/06 1
5 31/05/06 1
...

Je voudrais obtenir dans une seule grille les données de T_SAL et T_HAFF,
avec le TypeContrat de T_HST_CONTRAT, soit pour le 1er salarié :

Matricule Nom Prénom DateHist Type
00001 DURAND Pierre 31/01/06 CDD
00001 DURAND Pierre 28/02/06 CDD
00001 DURAND Pierre 31/03/06 CDI
00001 DURAND Pierre 30/04/06 CDI
00001 DURAND Pierre 31/05/06 CDI

Or en fonctionnant avec des jointures "classiques", je récupère des
résultats qui visiblement relèvent du produit cartésien :(

Je ne sais pas s'il est possible d'indiquer dans une instruction SELECT


que
la valeur à prendre est la date écoulée la plus proche (par exemple en
février récupérer le 02/01). De plus je ne peux pas altérer le modèle de
données...

Je cherche vraiment, si cela est possible, et même au détriment des
performances, à passer par un SELECT. Sinon je pense que créer une autre
table et insérer un trigger sur la table T_HAFF (référence du traitement)
sera possible, mais je voudrais éviter cela.

Pouvez-vous m'orienter ? D'avance merci et bonne journée.


Avatar
SQLpro [MVP]
Bonjour,

Le manque de précision de vos définition ne permet pas de vous donner
satisfaction. En effet à quoi correspond DateHist dans T_HST_CONTRAT la
date de début ou la date de fin du contrat ?

Il est difficile pour nous de deviner.

Je vais supposer que c'est la date de début du contrat...

OokieDookie a écrit :
Bonjour à tous,

Je suis confronté à une difficulté que je n'arrive pas à contourner avec une
syntaxe SELECT :

- Soit T_SAL la table des salariés
Matricule CompteurSal Nom Prénom
00001 1 DUPONT Pierre
00543 2 DURAND Etienne
...

- Soit T_HST_CONTRAT la table des contrats de travail :
Id CompteurSal DateHist TypeContrat InfoEnCours
1 1 02/01/06 CDD 0
2 1 02/05/06 CDI 1
...

- Soit T_HAFF la table des bulletins de salaires
Id Date CompteurSal
1 31/01/06 1
2 28/02/06 1
3 31/03/06 1
4 30/04/06 1
5 31/05/06 1
...

Je voudrais obtenir dans une seule grille les données de T_SAL et T_HAFF,
avec le TypeContrat de T_HST_CONTRAT, soit pour le 1er salarié :

Matricule Nom Prénom DateHist Type
00001 DURAND Pierre 31/01/06 CDD
00001 DURAND Pierre 28/02/06 CDD
00001 DURAND Pierre 31/03/06 CDI
00001 DURAND Pierre 30/04/06 CDI
00001 DURAND Pierre 31/05/06 CDI

Or en fonctionnant avec des jointures "classiques", je récupère des
résultats qui visiblement relèvent du produit cartésien :(

Je ne sais pas s'il est possible d'indiquer dans une instruction SELECT que
la valeur à prendre est la date écoulée la plus proche (par exemple en
février récupérer le 02/01). De plus je ne peux pas altérer le modèle de
données...

Je cherche vraiment, si cela est possible, et même au détriment des
performances, à passer par un SELECT. Sinon je pense que créer une autre
table et insérer un trigger sur la table T_HAFF (référence du traitement)
sera possible, mais je voudrais éviter cela.

Pouvez-vous m'orienter ? D'avance merci et bonne journée.



Voic la décomposition du problème :

CREATE TABLE T_SAL
(Matricule char(10),
CompteurSal int,
Nom char(32),
Prenom varchar(25))

CREATE TABLE T_HST
(id int identity,
CompteurSal int,
DateHist datetime,
TypeContrat varchar(10),
InfoEnCours int default 0)

CREATE TABLE T_HAFF
(id int identity,
CompteurSal int,
DDate datetime)

insert into T_SAL (matricule, compteurSal, Nom, prenom)
values ('00001', 1, 'Dupont', 'Pierre')
insert into T_SAL (matricule, compteurSal, Nom, prenom)
values ('00543', 2, 'Dupont', 'Etienne')

insert into T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (1, '20040105', 'cdd',0)
insert into T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (1, '20040615', 'cdi',1)
insert into T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (1, '20050410', 'cdi',1)
insert into T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (2, '20050502', 'cdi',1)
insert into T_HST (compteurSal, DateHist, TypeContrat,InfoEnCours )
values (2, '20060101', 'cdi',1)

insert into T_HAFF (compteurSal, ddate)
values (1, '20050330')
insert into T_HAFF (compteurSal, ddate)
values (1, '20050430')
insert into T_HAFF (compteurSal, ddate)
values (1, '20050530')
insert into T_HAFF (compteurSal, ddate)
values (1, '20050630')
insert into T_HAFF (compteurSal, ddate)
values (1, '20050730')
insert into T_HAFF (compteurSal, ddate)
values (2, '20050630')
insert into T_HAFF (compteurSal, ddate)
values (2, '20050730')

-- plage de validité des contrats :
SELECT compteurSal, DateHist AS DATE_DEBUT,
COALESCE((SELECT DATEADD(day, -1, MIN(DateHist))
FROM T_HST T2
WHERE T2.compteurSal = T1.compteurSal
AND T2.DateHist > T1.DateHist), '99991231')
AS DATE_FIN,
TypeContrat, InfoEnCours
FROM T_HST T1

-- mise en vue de cette requête :
CREATE VIEW V_HST
AS
SELECT compteurSal, DateHist AS DATE_DEBUT,
COALESCE((SELECT DATEADD(day, -1, MIN(DateHist))
FROM T_HST T2
WHERE T2.compteurSal = T1.compteurSal
AND T2.DateHist > T1.DateHist), '99991231')
AS DATE_FIN,
TypeContrat, InfoEnCours
FROM T_HST T1

-- interrogation :
SELECT *
FROM V_HST

-- jointure avec bulletin de paye :
SELECT *
FROM T_HAFF F
INNER JOIN V_HST T
ON F.ddate BETWEEN T.DATE_DEBUT AND T.DATE_FIN

Vous avez le début, à vous de trouver la fin...

PS : vous pouvevez vous absoudre de la vue en réintégrant la requête vue
dans la requête finale.


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
********************* http://www.datasapiens.com ***********************
Avatar
OokieDookie
Merci pour vos réponses. Je n'ai pas pu me connecter pendant quelque temps,
mais vos réponses sont aussi précises qu'efficaces ;)

Fred, pour info, la DateHist est la date de changement de contrat (passage
CDI à CDD).

Encore une fois merci beaucoup.

"OokieDookie" a écrit :

Bonjour à tous,

Je suis confronté à une difficulté que je n'arrive pas à contourner avec une
syntaxe SELECT :

- Soit T_SAL la table des salariés
Matricule CompteurSal Nom Prénom
00001 1 DUPONT Pierre
00543 2 DURAND Etienne
...

- Soit T_HST_CONTRAT la table des contrats de travail :
Id CompteurSal DateHist TypeContrat InfoEnCours
1 1 02/01/06 CDD 0
2 1 02/05/06 CDI 1
...

- Soit T_HAFF la table des bulletins de salaires
Id Date CompteurSal
1 31/01/06 1
2 28/02/06 1
3 31/03/06 1
4 30/04/06 1
5 31/05/06 1
...

Je voudrais obtenir dans une seule grille les données de T_SAL et T_HAFF,
avec le TypeContrat de T_HST_CONTRAT, soit pour le 1er salarié :

Matricule Nom Prénom DateHist Type
00001 DURAND Pierre 31/01/06 CDD
00001 DURAND Pierre 28/02/06 CDD
00001 DURAND Pierre 31/03/06 CDI
00001 DURAND Pierre 30/04/06 CDI
00001 DURAND Pierre 31/05/06 CDI

Or en fonctionnant avec des jointures "classiques", je récupère des
résultats qui visiblement relèvent du produit cartésien :(

Je ne sais pas s'il est possible d'indiquer dans une instruction SELECT que
la valeur à prendre est la date écoulée la plus proche (par exemple en
février récupérer le 02/01). De plus je ne peux pas altérer le modèle de
données...

Je cherche vraiment, si cela est possible, et même au détriment des
performances, à passer par un SELECT. Sinon je pense que créer une autre
table et insérer un trigger sur la table T_HAFF (référence du traitement)
sera possible, mais je voudrais éviter cela.

Pouvez-vous m'orienter ? D'avance merci et bonne journée.