Sélectionnez COUNT jours entre deux dates sauf le week-end


9

J'essaie d'obtenir le nombre de jours entre deux dates différentes, sauf les week-ends.

Je ne sais pas comment obtenir ce résultat.


1
Veuillez afficher la structure de votre table pour référence.Weekends signifie SAT et SUN?
Abdul Manaf

Réponses:


10

En supposant que par «week-end», vous voulez dire samedi et dimanche , cela peut être encore plus simple:

SELECT count(*) AS count_days_no_weekend
FROM   generate_series(timestamp '2014-01-01'
                     , timestamp '2014-01-10'
                     , interval  '1 day') the_day
WHERE  extract('ISODOW' FROM the_day) < 6;
  • Vous n'avez pas besoin d'un niveau de sous-requête supplémentaire pour generate_series(). SRF (set return functions), également appelé "table-fonctions", peut être utilisé comme les tables de la FROMclause.

  • Notez en particulier qui generate_series() inclut la limite supérieure dans la sortie, tant qu'un intervalle complet (3e paramètre) convient. La limite supérieure n'est exclue que si le dernier intervalle est tronqué, ce qui n'est pas le cas pour les jours entiers.

  • Avec le modèle ISODOWpour EXTRACT () , les dimanches sont signalés comme 7, selon la norme ISO. Permet une WHEREcondition plus simple .

  • Appelez plutôt generate_series()avec timestampentrée. Voici pourquoi:

  • count(*)est légèrement plus court et plus rapide que count(the_day), faire la même chose dans ce cas.

Pour exclure la limite inférieure et / ou supérieure, ajoutez / soustrayez 1 jour en conséquence. En règle générale, vous pouvez inclure la limite inférieure et exclure la limite supérieure:

SELECT count(*) AS count_days_no_weekend
FROM   generate_series(timestamp '2014-01-01'
                     , timestamp '2014-01-10' - interval '1 day'
                     , interval '1 day') the_day
WHERE  extract('ISODOW' FROM the_day) < 6;

3

Cet exemple énumère toutes les dates entre le 2013-12-15 et le 2014-01-02 (inclusivement). La deuxième colonne donne le jour de la semaine (numériquement, entre 0 et 6). La troisième colonne indique si le jour de la semaine est un samedi / dimanche ou non (vous devrez adapter ce que vous considérez comme un week-end) et c'est ce qui pourrait être utilisé pour compter les jours de la semaine.

select '2013-12-15'::date + i * interval '1 day',
       extract('dow' from '2013-12-15'::date + i * interval '1 day') as dow,
       case when extract('dow' from '2013-12-15'::date + i * interval '1 day') in (0, 6)
               then false
            else true end as is_weekday
from generate_series(0, '2014-01-02'::date - '2013-12-15'::date) i
;

3

En supposant qu'un week-end est le samedi et le dimanche, vous pouvez utiliser le SQL suivant.

select count(the_day) from 
    (select generate_series('2014-01-01'::date, '2014-01-10'::date, '1 day') as the_day) days
where extract('dow' from the_day) not in (0,6)

Remplacez les dates par vos choix et le (0,6) par les jours de la semaine que vous souhaitez exclure.

Quelques points dont vous devez prendre note: -

  1. Vous n'avez pas mentionné la version de PostgreSQL que vous utilisez. Cela fonctionne sur 9.1+ mais devrait fonctionner sur les versions inférieures.

  2. Les dates choisies sont incluses lors de l'utilisation de generate_series. Donc, si vous voulez des jours entre les deux, ajoutez 1 jour à chaque date.


0

Il y a deux ou trois choses que vous pouvez faire pour rendre cela plus facile. La méthode que j'utiliserais serait de s'assurer qu'un tableau de dates est disponible. Vous pouvez rapidement en créer un comme ceci:

CREATE TABLE [dbo].[Dates]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY(0,1),
[Date] Date NOT NULL unique,
isWeekend BIT NOT NULL DEFAULT(0)
)

Une fois le tableau créé, vous devriez pouvoir le remplir avec des données de date relativement rapidement.

set datefirst 6 --start date is saturday
INSERT INTO dbo.Dates(Date, isWeekend)
select 
    Date,
    case datepart(weekday,date) 
        --relies on DateFirst being set to 6
        when 2 then 1 
        when 1 then 1
        else 0
    end as isWeekend
from (
    select 
        dateadd(day, number - 1, 0) as date
    from (
        SELECT top 100000 row_number() over (order by o.object_id) as number
        FROM sys.objects o
            cross join sys.objects b
            cross join sys.objects c
    )numbers
)data

Vous pouvez ensuite écrire votre requête sous la forme d'un décompte rapide des enregistrements de cette table.

select count(*) as NumberOfWeekDays
from dbo.dates 
where isWeekend = 0
and date between '1 Jan 2013' and '31 Dec 2013'

0

Je vous suggère de créer une fonction à utiliser à tout moment et d'écrire moins; )

Ce code ci-dessus créera une fonction sql qui compte et renvoie le nombre de jours de week-end (samedi, dimanche). Tout comme vous aurez plus de flexibilité pour utiliser cette fonction.

CREATE OR REPLACE FUNCTION <YourSchemaNameOptional>.count_full_weekend_days(date, date)
RETURNS bigint AS
$BODY$
        select  COUNT(MySerie.*) as Qtde
        from    (select  CURRENT_DATE + i as Date, EXTRACT(DOW FROM CURRENT_DATE + i) as DiaDate
                 from    generate_series(date ($1) - CURRENT_DATE,  date ($2) - CURRENT_DATE ) i) as MySerie
        WHERE   MySerie.DiaDate in (6,0);
$BODY$
LANGUAGE 'SQL' IMMUTABLE STRICT;

Après cela, vous pouvez utiliser la fonction pour renvoyer uniquement le nombre de jours de week-end dans un intervalle. Voici l'exemple à utiliser:

SELECT <YourSchemaNameOptional>.count_full_weekend_days('2017-09-11', '2017-09-25') as days; --> RES: 4

Cette sélection doit renvoyer quatre car le premier et le deuxième jour sont lundi et nous avons 2 samedis et 2 dimanches entre eux.

Maintenant, pour ne renvoyer que les jours ouvrables (sans week-end), comme vous le souhaitez , faites simplement une soustraction, comme dans l'exemple ci-dessous:

SELECT (date '2017-09-25' - date '2017-09-11' ) - <YourSchemaName>.count_full_weekend_days('2017-09-11', '2017-09-25'); --> RES: 14 - 4 = 10

-2
-- Returns number of weekdays between two dates
SELECT count(*)  as "numbers of days 
FROM generate_series(0, (‘from_date’::date - 'todate'::date)) i 
WHERE date_part('dow', 'todate'::date + i) NOT IN (0,6)


-- Returns number of weekdays between two dates
SELECT count(*)  as days 
FROM generate_series(0, ('2014/04/30'::date - '2014/04/01'::date)) i 
WHERE date_part('dow', '2014/04/01'::date + i) NOT IN (0,6)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.