• Aucun résultat trouvé

The Compound Date Expression

Dans le document SQL for MySQL Developers (Page 152-156)

Common Elements

Exercise 5.24: Determine the values of the following numeric compound expressions:

5.13.3 The Compound Date Expression

MySQL enables you to calculate dates. For example, you can add a few days, months, or years to a date. The result of such a calculation is always a new date that is later (for addition) or earlier (for subtraction) than the original date expression.

When calculating the new date, the different number of days in the months and the leap years are taken into account. The calculation is done in a proleptic way, which means that no adjustment is made for the fact that, in the Gregorian calendar, the days October 5 to 14 in the year 1582 are missing completely. This also means that we can use a date such as January 1, 1000, even though this date is earlier than the point in time when the Gregorian calendar was introduced. That means that what we call January 1, 1200, according to the Gregorian calendar now, probably was called differently then.

A calculation with dates is specified with a compound date expression.

DEFINITION

<compound date expression> ::=

<scalar date expression> [ + | - ] <date interval>

<date interval> ::=

INTERVAL <interval length> <date interval unit>

<interval length> ::= <scalar expression>

<date interval unit> ::=

DAY | WEEK | MONTH | QUARTER | YEAR | YEAR_MONTH

A compound date expression starts with a scalar expression (such as a date lit-eral or a column specification with a date data type) followed by an intervalthat is added to or subtracted from the scalar expression.

An interval represents not a certain moment in time, but a certain period or length of time. This period is expressed in a number of days, weeks, months, quar-ters, or years, or a combination of these five. Interval literals help indicate how long, for example, a certain project lasted or how long a match took. Consider these examples of interval literals:

Interval Value

--- ---INTERVAL 10 DAY period of 10 days INTERVAL 100 WEEK period of 100 weeks INTERVAL 1 MONTH period of 1 month INTERVAL 3 YEAR period of 3 years

An interval is not a complete expression. It must always occur within a com-pound date expression, where it should be specified behind the +oroperators.

Example 5.44:For each penalty with a number higher than 5, get the payment number, the day on which the penalty was paid, and the date seven days after the payment date.

SELECT PAYMENTNO, PAYMENT_DATE, PAYMENT_DATE + INTERVAL 7 DAY FROM PENALTIES

WHERE PAYMENTNO > 5

The result is:

PAYMENTNO PAYMENT_DATE PAYMENT_DATE + INTERVAL 7 DAY --- ---

---6 1980-12-08 1980-12-15 7 1982-12-30 1983-01-06 8 1984-11-12 1984-11-19

Explanation: TheSELECTclause contains the expression DATE + INTERVAL 7 DAY.

The second part after the plus is the interval. The word INTERVAL precedes each interval. The word DAYis the interval unit,and7is the interval length.In this case, it is an interval of seven days.

As stated, an interval should always follow an expression with a date data type. The following statement, therefore, is not allowed:

SELECT INTERVAL 7 DAY

Example 5.45: Get the penalties that were paid between Christmas 1982 (December 25) and New Year’s Eve.

SELECT PAYMENTNO, PAYMENT_DATE FROM PENALTIES

WHERE PAYMENT_DATE >= '1982-12-25'

AND PAYMENT_DATE <= '1982-12-25' + INTERVAL 6 DAY

The result is:

PAYMENTNO PAYMENT_DATE ---

---7 1982-12-30

Explanation: In the second condition of the WHERE clause after the less than or equal to operator, an expression is specified that holds a calculation in which six days are added to the date of Christmas 1982.

When a compound date expression contains more than one interval, it is essential that no calculations be made with interval literals only. Interval literals can be added to dates only. For example, MySQL rejects the expression DATE + (INTERVAL 1 YEAR + INTERVAL 20 DAY). The reason is that brackets are used, and they force MySQL to add the two interval literals to each other first, which is not allowed. The next two formulations cause no problems:

DATECOL + INTERVAL 1 YEAR + INTERVAL 20 DAY (DATECOL + INTERVAL 1 YEAR) + INTERVAL 20 DAY

Instead of a literal, complex expressions can be used to specify an interval. In most cases, brackets are required. Consider a few more correct examples:

DATECOL + INTERVAL PLAYERNO YEAR + INTERVAL 20*16 DAY

DATECOL + INTERVAL (PLAYERNO*100) YEAR + INTERVAL LENGTH('SQL') DAY

The scalar expression used to indicate the interval does not have to be a value with an integer data type; decimals and floats are allowed as well. However, MySQL rounds the value first. The part after the decimal point simply is removed, and the value is rounded up or down. So the following two expressions have the same value:

DATECOL + INTERVAL 1.8 YEAR DATECOL + INTERVAL 2 YEAR

In many of the calculations with dates and interval literals, MySQL acts as expected. For example, if we add the interval three days to the date literal

'2004-01-12', the value January 15, 2004results. But it is not always this easy. Consider the processing rules with regard to interval literals.

When a random interval is added to an incorrect date literal, MySQL returns the null value. For example, this is the case for the expression '2004-13-12' + INTERVAL 1 DAY. However, if this happens, MySQL does not return an error mes-sage. But if you want to see the message, you can retrieve it with SHOW WARNINGS

statement.

Example 5.46:Add one day to the date literal '2004-13-12'; next show the error messages.

SELECT '2004-13-12' + INTERVAL 1 DAY SHOW WARNINGS

The result is:

Level Code Message

--- ---- ---Warning 1292 Truncated incorrect datetime value: '2004-13-12'

When an interval of several days is added to a correct date (existing or non-existing), the new date is converted into a sequence number first. This sequence number indicates what day it is since the beginning of year 0. Next, the number of days are added or subtracted. The new sequence number is converted again to the corresponding date.

IfSQL_MODE has the ALLOW_INVALID_DATES setting switched to on, MySQL can perform calculations with correct nonexisting dates. A nonexisting date such as February 31, 2004 is converted first to a sequence number that is equal to that of the date March 2, 2004. Therefore, the expression '2004-04-31' + INTERVAL 1 DAY

returns May 2, 2004 as result because '2004-04-31' is converted to May 1, 2004 first.'2004-04-31' + INTERVAL 31 DAYgives June 1, 2004 as result.

When an interval unit of weeks is specified, the way of processing is compara-ble to that of the days. One week equals seven days.

When the interval unit months is used, one month does not stands for 31 days.

Special rules apply when months are used for calculation. When a number of months are added to a date, the months component is increased by that number.

When that date does not exist, it is rounded downto the last date of the correspon-ding month. Therefore, '2004-01-31' + INTERVAL 1 MONTHgives29 February 2004

as result. If the value of the months component is greater than 12, then 12 is sub-tracted, and the years component is increased by 1.

When a number of months is subtracted from a date, MySQL uses the same method of processing.

If a interval unit of quarters is specified, the processing method is comparable to that for months. With that, one quarter equals three months.

For calculations with years, certain rules apply that are comparable to those for months. With the years component, the number of years is added to or subtracted

from it. If in a leap year, one year is added to February 29, it is rounded down, and the result is February 28. If one year is added to a correct but nonexisting date, the days component is not changed. The result is a correct but nonexisting date again.

For example, the result of '2004-02-31' + INTERVAL 1 YEARis February 31, 2004.

Because of these processing rules, using multiple interval literals in one com-pound date expression sometimes leads to unexpected results. See the following examples and compare examples three to four, five to six, and seven to eight. Even when the interval literals are reversed, the result is different. In these examples, assume that the setting ALLOW_INVALID_DATESfor the variable SQL_MODEis turned on.

Compound date expression Value ---'2004-02-31' + INTERVAL 1 MONTH – INTERVAL 1 MONTH 2004-02-29 '2004-02-31' + INTERVAL 1 DAY – INTERVAL 1 DAY 2004-03-02 '2004-02-31' + INTERVAL 1 YEAR + INTERVAL 1 DAY 2005-03-04 '2004-02-31' + INTERVAL 1 DAY + INTERVAL 1 YEAR 2005-03-03 '2004-02-31' + INTERVAL 1 MONTH + INTERVAL 1 DAY 2004-04-01 '2004-02-31' + INTERVAL 1 DAY + INTERVAL 1 MONTH 2004-04-03 '2000-02-29' + INTERVAL 1 YEAR – INTERVAL 1 DAY 2005-02-27 '2000-02-29' – INTERVAL 1 DAY + INTERVAL 1 YEAR 2005-02-28

MySQL also has a combined interval unit called YEAR_MONTH. For example, the expression'2004-02-18' + INTERVAL '2-2' YEAR_MONTH has the same result as

'2004-02-18' + INTERVAL 2 YEAR + INTERVAL 2 MONTH. See how the two numbers are enclosed by quotation marks (so they actually form one alphanumeric expres-sion) and separated by a hyphen.

Dans le document SQL for MySQL Developers (Page 152-156)