Tout d'abord, ta définition de jour ouvrable semble exclure les jours fériés ... mais passons, c'est pas le sujet.
Ensuite, obtenir le résultat sans passer par une fonction (juste une requête donc) me paraît un peu illusoire (mais je ne maîtrise pas postgres à fond non plus !).
Cependant, je me permets de critiquer ta fonction du fait qu'elle est très coûteuse en temps avec des intervalles longs, si en plus on l'applique à de nombreux enregistrements ...
Ma proposition est donc un truc du style suivant (j'ai laissé les raise notice de débogage à tout hazard) ; ce qui donne (ça va faire mal !) :
CREATE FUNCTION nbJoursOuvrables(DATE, DATE) RETURNS INTEGER AS'
DECLARE
debut ALIAS FOR 1ドル;
fin ALIAS FOR 2ドル;
debut_d DATE;
fin_d DATE;
debut_j INTEGER;
fin_j INTEGER;
periode INTEGER;
nb INTEGER;
BEGIN
debut_j := to_char( debut , ''D'' )::INTEGER;
IF debut_j <> 2 THEN
debut_d := date_mii( debut, 7-debut_j+3 ); -- lundi prédécent
ELSE
debut_d := debut; -- lundi courant
END IF;
RAISE NOTICE ''debut_j = %, debut_d = %'', debut_j, debut_d;
fin_j := to_char( fin, ''D'')::INTEGER;
IF fin_j <> 1 THEN
fin_d := date_mii( fin, fin_j-7-1 );
ELSE
fin_d := fin;
END IF;
RAISE NOTICE ''fin_j = %, fin_d = %'', fin_j, fin_d;
periode = date_mi( fin_d, debut_d )+1;
RAISE NOTICE ''periode = %'', periode;
nb := periode - periode / 7 * 2; -- nb jours sans sam/dim
RAISE NOTICE ''periode - s/m = %'', nb;
IF date_mi( fin_d, debut_d )>7 THEN
IF fin_j <> 7 THEN
nb := nb - (debut_j-1) -(7-fin_j-2 );
ELSE
nb := nb - (debut_j-1) -(7-fin_j-1);
END IF;
ELSE
nb := nb - debut_j + 2;
END IF;
RETURN nb;
END;'
LANGUAGE 'plpgsql';
Le principe de la fonction consiste à repérer les dates limites (lundi, dimanche usuels) englobant au mieux les dates données. On obtient donc un nombre de semaines entières qu'il suffit de diviser par 7 et multiplier par 2 pour obtenir le nombre de samedis/dimaches de cette période. Enfin, il faut ajuster suivant la position du dernier jour i.e un samedi déjà compté ou non.
La fonction testée sommairement à l'air vachement balèse mais c'est beaucoup plus léger que de boucler sur les jours à mon avis surtout si les dates sont très espacées ...
A++
P.S : C'est pas toi qui recherchait comment déterminer si deux périodes se chevauchent ? ... je viens de remarquer que PostgreSQL a justement une fonction overlaps(date, date, date, date) ... à bon codeur ...
# peut-être une piste
Posté par idiotduvillage . En réponse au message SQL toujours : requête sur une non-table..... Évalué à 3.
Ensuite, obtenir le résultat sans passer par une fonction (juste une requête donc) me paraît un peu illusoire (mais je ne maîtrise pas postgres à fond non plus !).
Cependant, je me permets de critiquer ta fonction du fait qu'elle est très coûteuse en temps avec des intervalles longs, si en plus on l'applique à de nombreux enregistrements ...
Ma proposition est donc un truc du style suivant (j'ai laissé les raise notice de débogage à tout hazard) ; ce qui donne (ça va faire mal !) :
CREATE FUNCTION nbJoursOuvrables(DATE, DATE) RETURNS INTEGER AS'
DECLARE
debut ALIAS FOR 1ドル;
fin ALIAS FOR 2ドル;
debut_d DATE;
fin_d DATE;
debut_j INTEGER;
fin_j INTEGER;
periode INTEGER;
nb INTEGER;
BEGIN
debut_j := to_char( debut , ''D'' )::INTEGER;
IF debut_j <> 2 THEN
debut_d := date_mii( debut, 7-debut_j+3 ); -- lundi prédécent
ELSE
debut_d := debut; -- lundi courant
END IF;
RAISE NOTICE ''debut_j = %, debut_d = %'', debut_j, debut_d;
fin_j := to_char( fin, ''D'')::INTEGER;
IF fin_j <> 1 THEN
fin_d := date_mii( fin, fin_j-7-1 );
ELSE
fin_d := fin;
END IF;
RAISE NOTICE ''fin_j = %, fin_d = %'', fin_j, fin_d;
periode = date_mi( fin_d, debut_d )+1;
RAISE NOTICE ''periode = %'', periode;
nb := periode - periode / 7 * 2; -- nb jours sans sam/dim
RAISE NOTICE ''periode - s/m = %'', nb;
IF date_mi( fin_d, debut_d )>7 THEN
IF fin_j <> 7 THEN
nb := nb - (debut_j-1) -(7-fin_j-2 );
ELSE
nb := nb - (debut_j-1) -(7-fin_j-1);
END IF;
ELSE
nb := nb - debut_j + 2;
END IF;
RETURN nb;
END;'
LANGUAGE 'plpgsql';
Le principe de la fonction consiste à repérer les dates limites (lundi, dimanche usuels) englobant au mieux les dates données. On obtient donc un nombre de semaines entières qu'il suffit de diviser par 7 et multiplier par 2 pour obtenir le nombre de samedis/dimaches de cette période. Enfin, il faut ajuster suivant la position du dernier jour i.e un samedi déjà compté ou non.
La fonction testée sommairement à l'air vachement balèse mais c'est beaucoup plus léger que de boucler sur les jours à mon avis surtout si les dates sont très espacées ...
A++
P.S : C'est pas toi qui recherchait comment déterminer si deux périodes se chevauchent ? ... je viens de remarquer que PostgreSQL a justement une fonction overlaps(date, date, date, date) ... à bon codeur ...