2016-06-07 4 views
0

Я написал хранимую процедуру, чтобы получить неделю с даты, она также возвращает дату в начале недели, а также номер недели и год.MariaDB начало недели дата и неделя номер 1 до 52

Я знаю о функции «НЕДЕЛЯ», однако это не дает мне дату в начале недели, и я не знаю о функции, которая делает это с учетом недели и года.

Вопрос:
Как я могу получить «дата» в начале недели данный номер недели? Когда начало недели передается в качестве дневного индекса, 0 = воскресенье, 1 = понедельник и т. Д.

Моя текущая функция не всегда работает, и если первый день недели - понедельник, то воскресенье падает на следующей неделе, а не в конце той же недели, как мне бы хотелось.

+0

Может ли кто-нибудь помочь в решении этой проблемы? – SPlatten

ответ

0

решаемые, я снова написал хранимую процедуру:

exitProc:BEGIN 
    #-- 
    # Procedure: 
    # weekFromDate 
    # 
    # Parameters: 
    # vcCompKey, the key associated with the company 
    # dtDate, the date to translate 
    # dtOutSOW, returned start of week date 
    # siOutWeek, returned week number 
    # siOutYear, returned year 
    #-- 
     DECLARE siDIY   SMALLINT; #Day in year 
     DECLARE siFDOW   SMALLINT; #First day of week 
     DECLARE siGoBack  SMALLINT;  #Flag used to check for last year 
     DECLARE siRmonth  SMALLINT; #Reference Month 
     DECLARE siRyear  SMALLINT; #Reference Year 
     DECLARE dtSOY   DATE;  #Date of start of year 
     DECLARE vcFMDOY  VARCHAR(12);#First month and day of year 
     DECLARE vcFDOW   VARCHAR(12);#First day of the week 
     DECLARE vcDYSOW  VARCHAR(80);#Days of week 
    #Get the first day of the week for the specified company 
     SET vcFDOW = vcGetParamValue(vcCompKey, 'Var:First day of week'); 

    IF (vcFDOW IS NULL) THEN 
    #No entry found, abort! 
     LEAVE exitProc; 
    END IF; 
    #Get the first month and day of the year for the specified company 
    SET vcFMDOY = vcGetParamValue(vcCompKey, 'Var:First day of year'); 

    IF (vcFMDOY IS NULL) THEN 
    #No entry found, abort! 
     LEAVE exitProc; 
    END IF; 
    #Set-up days of week 
    SET vcDYSOW = 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday'; 
    #Get the first day of the week index base 1 
    SET siFDOW = FIND_IN_SET(LOWER(vcFDOW), LOWER(vcDYSOW)) - 1; 
    #Get the reference month and year 
    SET siRmonth = MONTH(dtDate); 
    SET siRyear = YEAR(dtDate); 
    SET dtSOY = DATE(CONCAT(siRyear, '/', vcFMDOY)); 
    #Calculate the start of week date 
    SET dtOutSOW = DATE_SUB(dtDate, INTERVAL (DAYOFWEEK(dtDate) - siFDOW) DAY) + 1; 
    #Calculate the day in year 
    SET siDIY = DATEDIFF(dtOutSOW, dtSOY); 
    #Do we need to go back to the end of the previous year? 
    SET siGoBack = YEAR(dtDate) - YEAR(dtOutSOW); 

    IF siGoBack < 0 Or siDIY < 0 Or dtDate < dtOutSOW THEN 
    #Yes 
     IF YEAR(dtOutSOW) = YEAR(dtDate) THEN 
      SET dtOutSOW = DATE_SUB(dtOutSOW, INTERVAL 7 DAY); 
     END IF; 
     SET dtSOY = DATE(CONCAT(YEAR(dtOutSOW), '/', vcFMDOY)); 
     SET siDIY = DATEDIFF(dtOutSOW, dtSOY); 
    END IF;  
    #Calculate the week no. and year 
    SET siOutWeek = (siDIY/7) + 1; 
    SET siOutYear = YEAR(dtOutSOW); 
END 

Эта процедура делает использование других таблиц в моей базе данных и позволяет компаниям иметь разное начало лет.

0

Использование Sequence двигатель. Вы можете адаптировать следующий пример, как нужно:

MariaDB [_]> SHOW ENGINES\G 
. 
. 
. 
*************************** 3. row *************************** 
     Engine: SEQUENCE 
    Support: YES 
    Comment: Generated tables filled with sequential values 
Transactions: YES 
      XA: NO 
    Savepoints: YES 
. 
. 
. 

MariaDB [_]> SET @`year` := 2016, 
      ->  @`mode` := 1, 
      ->  @`week` := 23; 
Query OK, 0 rows affected (0.00 sec) 

MariaDB [_]> SELECT 
      -> `der`.`date`, 
      -> `der`.`week`, 
      -> `der`.`year` 
      -> FROM (
      -> SELECT 
      ->  `der`.`date`, 
      ->  WEEK(`der`.`date`, @`mode`) `week`, 
      ->  YEAR(`der`.`date`) `year` 
      -> FROM (
      ->  SELECT 
      ->  DATE_ADD(CONCAT(@`year`, '-01-01'), INTERVAL `s`.`seq` DAY) `date` 
      ->  FROM 
      ->  seq_0_to_365 `s` 
      -> ) `der` 
      ->) `der` 
      -> WHERE 
      -> `der`.`week` = @`week` AND 
      -> `der`.`year` = @`year`; 
+------------+------+------+ 
| date  | week | year | 
+------------+------+------+ 
| 2016-06-06 | 23 | 2016 | 
| 2016-06-07 | 23 | 2016 | 
| 2016-06-08 | 23 | 2016 | 
| 2016-06-09 | 23 | 2016 | 
| 2016-06-10 | 23 | 2016 | 
| 2016-06-11 | 23 | 2016 | 
| 2016-06-12 | 23 | 2016 | 
+------------+------+------+ 
7 rows in set (0.01 sec) 
+0

Спасибо, я попробую. – SPlatten

+0

Я подозреваю, что использование «последовательности» таким образом приводит к вычислению данных за весь год, только для того, чтобы вернуть результаты одного дня? –

+0

@ RickJames: Правильно, это недостаток решения. – wchiquito

0

В качестве теста я найти начало текущей недели, первая нота:

mysql> SELECT NOW(), WEEK(NOW()); 
+---------------------+-------------+ 
| NOW()    | WEEK(NOW()) | 
+---------------------+-------------+ 
| 2016-06-18 12:10:58 |   24 | 
+---------------------+-------------+ 

Тогда это мясо функции:

mysql> SELECT '2016-01-01' 
      + INTERVAL 7*24 
      - DAYOFWEEK('2016-01-01') 
      + 1 DAY; 
+----------------------------------------------------------------+ 
| '2016-01-01' + INTERVAL 7*24 - DAYOFWEEK('2016-01-01') + 1 DAY | 
+----------------------------------------------------------------+ 
| 2016-06-12              | 
+----------------------------------------------------------------+ 

'2016-01-01' является началом год в вопросе.
24 Номер WEEK().
+ 1 DAY - это компенсация за начало недели.
Что-то еще нужно сделать для обработки вашего варианта того, в какой день начинается неделя.