2014-09-18 2 views
4

Я пытаюсь найти число Xdays (понедельники, пятницы и т. Д.) Через месяц. Я мог бы всегда проходить через дни в течение месяца, находить их день недели, подводить итоги и хранить его, но я думаю, что есть лучший способ сделать это.График конкретных дней недели по времени

В идеале я хотел бы получить результат за «сколько понедельн, дней и пятниц (или сколько дней) в сентябре 2015 года?».

Я могу найти, как получить недельные дни в течение определенного периода времени. Я могу получить такую ​​информацию из дат, уже введенных в базу данных, но я хочу знать, что есть вторник, даже если на этот день нет данных.

+0

Вы могли бы написать скрипт, который проверяет, что в первый день месяца, и сколько дней в месяце и экстраполировать оттуда. – Leeish

ответ

-2

, как @Leeish сказал:

«Вы могли бы написать скрипт, который проверяет, что первый день месяц есть, и сколько дней в месяце и экстраполировать там»

(я только иметь доступ к MS Sql, но должен быть похож)

это поможет вам в первый день месяца, в текстовом формате («Понедельник», например):

SELECT DATENAME(dw,DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)) 

это поможет вам, сколько дней в месяце:

select datediff(d, GETDATE(), dateadd(m, 1, GETDATE())) 

надеюсь, что это помогает.

+0

'DATEDIFF',' DATENAME', 'GETDATE' не являются функциями Oracle. –

-1

В Oracle вы можете использовать маски формата даты, чтобы узнать, в какой день определенная дата. Следующий пример подсчитывает все в понедельник в месяце 9 (сентябре) 2015

SELECT COUNT(*) 
FROM (SELECT RTRIM(TO_CHAR(TO_DATE(TO_CHAR(LEVEL, '09')||'09'||'2015','DDMMYYYY'),'DAY')) AS days 
     FROM dual 
     WHERE ROWNUM <= EXTRACT(DAY FROM LAST_DAY(TO_DATE('09'||'2015','MMYYYY'))) 
     CONNECT BY LEVEL=ROWNUM 
     ) 
WHERE days = 'MONDAY' 
     ; 
1

Вариант ответа Михель T, используя trunc с параметром месяца формата, чтобы получить первый день месяца:

select count(*) 
from 
    (select trunc(sysdate, 'MM') + (level - 1) dt 
    from dual 
    connect by level <= extract(day from last_day(trunc(sysdate, 'MM')))) 
where to_char(dt, 'FMDAY') = 'MONDAY' 
1

итерационный подход, основанный на PL/SQL PIPELINED functions:

CREATE OR REPLACE TYPE days_tbl AS TABLE OF DATE; 

CREATE OR REPLACE FUNCTION days_for_month(basedate IN DATE) 
RETURN days_tbl PIPELINED 
AS 
    month VARCHAR(2); 
    thedate DATE := TRUNC(basedate,'MON'); 
BEGIN 
    LOOP 
     PIPE ROW(thedate); 
     EXIT WHEN thedate = LAST_DAY(thedate); 
     thedate := thedate + 1; 
    END LOOP; 
END; 

Основы использования:

SELECT COLUMN_VALUE 
    FROM TABLE(days_for_month(SYSDATE)) 
    WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') = 'MONDAY'; 

Функция может быть оптимизирована для ваших конкретных потребностей (найти заданный день по имени), но держать его более общий характер позволяет некоторую гибкость использования, как:

SELECT COLUMN_VALUE 
    FROM TABLE(days_for_month(SYSDATE)) 
    WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') IN ('SUNDAY','SATURDAY'); 

Учитывая ваш пример:

«Сколько понедельников, понедельников и пятниц (или любых дней) в сентябре 2015 года?».

SELECT COUNT(*) 
    FROM TABLE(days_for_month(TO_DATE('09-2015','MM-YYYY'))) 
    WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') IN ('MONDAY','TUESDAY','FRIDAY'); 

Производство:

COUNT(*) 
13 

Или, если вам нужна деталь:

SELECT T.D, COUNT(*) 
    FROM TABLE(days_for_month(TO_DATE('09-2015','MM-YYYY'))), 
     (SELECT 'MONDAY' AS D FROM DUAL UNION 
     SELECT 'TUESDAY' FROM DUAL UNION 
     SELECT 'FRIDAY' FROM DUAL) T 
    WHERE TO_CHAR(COLUMN_VALUE,'FMDAY') = T.D 
    GROUP BY T.D 

Для производства:

D  COUNT(*) 
TUESDAY 5 
FRIDAY 4 
MONDAY 4 
0

Это дает первый вторник в Г вэн месяц:

NEXT_DAY(TRUNC(DATE '2014-09-19', 'MM')-1, 'TUESDAY') 

Это дает вам в прошлый вторник в данном месяце:

NEXT_DAY(LAST_DAY(DATE '2014-09-19')-7, 'TUESDAY') 

Таким образом, вы можете объединить его:

SELECT 1 + (NEXT_DAY(LAST_DAY(DATE '2014-09-19')-7, 'TUESDAY') - NEXT_DAY(TRUNC(DATE '2014-09-19', 'MM')-1, 'TUESDAY'))/7 AS TUESDAYS_IN_MONTH 
FROM dual; 
+0

, вы можете проверить это на все дни. Он не дает правильного ответа по понедельникам в сентябре 2014 года. – DrabJay

+0

Я исправил его, теперь он должен работать лучше –

Смежные вопросы