태그 보관물: postgresql

postgresql

주말을 제외한 두 날짜 사이에서 COUNT 일을 선택하십시오. 다른 날짜 사이의 일 수를

주말을 제외하고 두 개의 다른 날짜 사이의 일 수를 얻으려고합니다.

이 결과를 얻는 방법을 모르겠습니다.



답변

“주말”이라는 말이 토요일일요일 을 의미한다고 가정하면 , 훨씬 더 간단 할 수 있습니다.

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;
  • 에 대한 추가 하위 쿼리 수준이 필요하지 않습니다 generate_series(). “테이블 함수”라고도하는 SRF (세트 리턴 함수)는 FROM절의 테이블처럼 사용할 수 있습니다 .

  • 특히 전체 간격 (3 번째 매개 변수)이 맞는 한 출력에 상한 을 generate_series() 포함 합니다 . 상한은 마지막 간격이 잘린 경우에만 제외되며 전체 날짜의 경우에는 해당되지 않습니다.

  • EXTRACT () 패턴 ISODOW 사용하면 일요일이 7ISO 표준에 따라로 보고됩니다 . 더 간단한 WHERE조건을 허용합니다 .

  • 오히려 전화 generate_series()timestamp입력. 이유는 다음과 같습니다.

  • count(*)이 경우에도 약간 짧고 빠릅니다 count(the_day).

하한 및 / 또는 상한 을 제외 하려면 그에 따라 하루를 더하거나 빼십시오. 일반적으로 하한을 포함하고 상한을 제외 할 수 있습니다.

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;


답변

이 예는 2013-12-15와 2014-01-02 (포함) 사이의 모든 날짜를 열거합니다. 두 번째 열은 요일을 나타냅니다 (숫자, 0에서 6 사이). 세 번째 열은 요일이 토요일 / 일요일인지 여부를 표시하고 (주말을 고려하여 조정해야 함) 주중을 계산하는 데 사용할 수있는 항목을 나타냅니다.

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
;


답변

주말이 토요일과 일요일이라고 가정하면 다음 SQL을 사용할 수 있습니다.

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)

날짜를 선택 사항으로 바꾸고 (0,6)을 제외하려는 요일로 바꾸십시오.

몇 가지주의해야 할 사항 :-

  1. 실행중인 PostgreSQL 버전에 대해서는 언급하지 않았습니다. 이것은 9.1 이상에서 작동하지만 하위 버전에서는 작동해야합니다.

  2. generate_series를 사용할 때 선택한 날짜가 포함됩니다. 따라서 사이에 날짜를 원하면 각 날짜에 1 일을 추가하십시오.


답변

이것을 쉽게하기 위해 할 수있는 몇 가지가 있습니다. 내가 사용하는 방법은 날짜 테이블을 사용할 수 있는지 확인하는 것입니다. 다음과 같이 빠르게 만들 수 있습니다.

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

테이블이 작성되면 비교적 빠르게 날짜 데이터로 테이블을 채울 수 있어야합니다.

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

그런 다음이 테이블에서 빠른 레코드 수로 쿼리를 작성할 수 있습니다.

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


답변

나는 당신이 원할 때마다 사용할 함수를 작성하고 적게 쓸 것을 제안합니다. )

위의 코드는 주말 일 수를 계산하고 반환하는 sql 함수를 작성합니다 (Sat, Sun). 이 기능을 사용할 수있는 유연성이 향상되었습니다.

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;

그 후, 함수 사용하여 간격 으로 주말 수만 리턴 할 수 있습니다 . 사용하는 예제는 다음과 같습니다.

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

첫 번째와 두 번째 날이 월요일이므로이 선택은 4를 반환해야하며 두 토요일과 일요일 사이에 일요일이 있습니다.

이제, 단지 영업일 돌아갑니다 (주말없이)를 당신이 원하는대로 , 바로 아래의 예처럼 뺄셈을합니다

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


답변

-- 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)


답변