Autojointure avec critères

Résolu
cs_Sieurcoug Messages postés 10 Date d'inscription jeudi 26 février 2009 Statut Membre Dernière intervention 16 avril 2012 - 29 juin 2010 à 17:58
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 - 1 juil. 2010 à 19:43
Bonjour à tous,

Je soumets à votre réflexion un petit exercice a priori simple mais que je n'arrive pas à résoudre.

J'ai une table d'actions (tâches de travail en quelque sorte), dont j'extrais certaines avec un critère. Jusque là ok.
Je souhaite pour ces actions extraites savoir s'il y a une action suivante faite dans les 2 jours suivants, ou pas (on est toujours sur la même table).
En clair :
- Soit une action est faite dans les 2 jours suivant une tâche extraite ==> réponse à sortir : 'OUI'
- Soit pas d'action ou une action au délà de 2 jours ==> réponse à sortir : 'NON'


Voici ma requête pour l'instant. Celle-ci me retourne le bon nombre d'enregistrements. Il manque le fameux OUI/NON pour chaque enregistrement.
Je précise pour la compréhension que pour ces actions, il y une notion de "demande" (colonnes SRA_SR_ID/SR_NUM) qu'on pourrait considérer comme un projet. Donc pour chaque projet il y a plusieurs actions.

SELECT DISTINCT
tActions.TODO_CD AS 'Type Action'
,tActions.NAME AS 'Résumé Action'
,Convert(Char(10), tActions.CREATED, 103) + ' ' + Convert(Char(8), tActions.CREATED, 108) AS 'Date Heure Action'
,tActions.SRA_SR_ID AS 'N° Demande'
FROM samprd.dbo.S_EVT_ACT tActions
FULL OUTER JOIN samprd.dbo.S_SRV_REQ tDemande
ON tActions.SRA_SR_ID = tDemande.SR_NUM
FULL OUTER JOIN samprd.dbo.S_EVT_ACT tActionSuivante
ON tActionSuivante.SRA_SR_ID = tDemande.SR_NUM
--AND tActionSuivante.CREATED > tActions.CREATED
WHERE 
tActions.NAME LIKE '%bla bla bla%'
AND NOT tActionSuivante.NAME LIKE '%bla bla bla%'
and tActionSuivante.SRA_SR_ID = tActions.SRA_SR_ID

ORDER BY tActions.SRA_SR_ID



Ai-je bien exposé mon problème ?
J'ai essayé avec des CASE WHEN, des curseurs, mais sans succès.


Ensuite la petite subtilité consistera à ne pas compter les jours fériés et week-ends dans les 2 jours, mais ça je devrais y arriver en adaptant ma fonction :
http://www.sqlfr.com/codes/CALCUL-DIFFERENCE-DATE-FONCTION-JOURS-FERIES-TRAVAILLES-PLAGE_50022.aspx


Merci d'avance pour vos avis !!

3 réponses

nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
30 juin 2010 à 00:01
Salut,

select *,
 case when DateAction between getdate() and (DATEADD(D,2,GETDATE())) THEN 1
 else 0
 end as selection	
 from dbo.Action



base sur la table

Nom        DateAction              selection
---------- ----------------------- -----------
A          2010-06-26 00:00:00.000 0
B          2010-12-30 00:00:00.000 0
C          2010-01-01 00:00:00.000 0
D          2010-06-30 00:00:00.000 1

(4 ligne(s) affectée(s))


PS evites les FULL OUTER JOIN a moins que c'est vraiment justifié
Normalement tu es capable de faire quasi tout avec le INNER et le LEFT


EXEMPLE sur table A et B avec une FK de table A sur la PK de B
INNER 
TABLEA.PK1 TABLEA.FK TABLEB.PK1


LEFT 
TABLEA.PK1 TABLEA.FK TABLEB.PK1
TABLEA.PK1 TABLEA.FK NULL

RIGHT 
TABLEA.PK1 TABLEA.FK TABLEB.PK1
NULL       NULL      TABLEB.PK1

FULL 
TABLEA.PK1 TABLEA.FK TABLEB.PK1
NULL       NULL      TABLEB.PK1
TABLEA.PK1 TABLEA.FK NULL




En esperant que tu peux inclure ta fonction ;-)
Sinon il faut passer par des variables SQL dans la PS ca peut dépanner ;-)

Bon dev
3
cs_Sieurcoug Messages postés 10 Date d'inscription jeudi 26 février 2009 Statut Membre Dernière intervention 16 avril 2012
1 juil. 2010 à 18:11
Bonjour,

Merci nhervagault pour l'astuce, je suis passé en INNER JOIN, et la requête est d'ailleurs plus rapide !
En revanche la solution que tu me donnes, adaptée dans ma requête ne fonctionne pas. Ai-je mal retranscris ?


SELECT DISTINCT
tActions.TODO_CD AS 'Type Action', 
tActions.NAME AS 'Résumé Action',
tActions.CREATED AS 'Date Heure Action',
case 
when tActionSuivante.CREATED between tActions.CREATED and (DATEADD(D,2,tActions.CREATED)) THEN 'OUI'
else 'NON'
end as 'Réussite'

FROM samprd.dbo.S_EVT_ACT tActions
INNER JOIN samprd.dbo.S_SRV_REQ tDemande
ON tActions.SRA_SR_ID = tDemande.SR_NUM
INNER JOIN samprd.dbo.S_EVT_ACT tActionSuivante
ON tActionSuivante.SRA_SR_ID = tDemande.SR_NUM
WHERE 
tActions.NAME LIKE '%bla bla bla%'
AND NOT tActionSuivante.NAME LIKE '%bla bla bla%'
and tActionSuivante.SRA_SR_ID = tActions.SRA_SR_ID

ORDER BY tActions.SRA_SR_ID



En fait elle me retourne en majorité OUI et NON pour chaque enregistrement, et bien plus si j'en lève le DISTINCT.
Car pour chaque ligne extraite avec '%bla bla bla%' (action initiale), il y a très souvent des actions ultérieures, mais pas forcément dans les 2 jours. Je veux uniquement savoir si l'action qui suit immédiatement l'action '%bla bla bla%' est dans les 2 jours suivants.
Oui, c'est bien compliqué mon truc... :-)
Faudrait-il passer par des tables temporaires ?
0
nhervagault Messages postés 6063 Date d'inscription dimanche 13 avril 2003 Statut Membre Dernière intervention 15 juillet 2011 37
1 juil. 2010 à 19:43
OK

C'est normal pour l'optimisation,
le full fait un produit cartesien
et le inner join un parcours par lookup recherche


Pour l'autre question, je ne vois pas trop
tu as nb lignes tActions * tActionSuivante qui reponds à ta demande

il faut utiliser un group by dans le cas ou tu veux que tActions
et mettre une clause d'agregat min ou max sur
tout les tActionSuivante.CREATED
0
Rejoignez-nous