Emulate Oracle's ROUND() function for dates (#468) · bufferapp/bigquery-utils@0908267 · GitHub
Skip to content

Commit 0908267

Browse files
authored
Emulate Oracle's ROUND() function for dates (GoogleCloudPlatform#468)
1 parent a91e1b8 commit 0908267

4 files changed

Lines changed: 124 additions & 3 deletions

File tree

‎release/terraform/main.tf‎

Lines changed: 0 additions & 2 deletions

‎udfs/migration/oracle/README.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ directory will be automatically synchronized to the `bqutil` project within the
77

88
## UDFs
99

10-
Nothing here yet, check back soon...
10+
* [round_datetime](#round_datetimedt-datetime-format-string)
11+
12+
## Documentation
13+
14+
### [round_datetime(d DATETIME, format STRING)](round_datetime.sqlx)
15+
Emulates the `ROUND(DATE, VARCHAR)` function from Oracle as [documented here](https://docs.oracle.com/cd/B14117_01/server.101/b10759/functions121.htm).
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
config { hasOutput: true }
2+
/*
3+
* Copyright 2024 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
CREATE OR REPLACE FUNCTION ${self()}(d DATETIME, format STRING)
19+
RETURNS DATETIME
20+
OPTIONS (
21+
description="Emulates the behavior of Oracle's ROUND function for dates"
22+
)
23+
AS (
24+
CASE
25+
WHEN format = "YEAR" OR format = "SYYYY" OR format = "YYYY" OR format = "SYEAR" OR format = "YYY" OR format = "YY" OR format = "Y" THEN
26+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 6 MONTH), YEAR)
27+
WHEN format = "IYYY" OR format = "IYY" OR format = "IY" OR format = "I" THEN
28+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 6 MONTH), YEAR)
29+
WHEN format = "Q" THEN
30+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 3 MONTH), QUARTER)
31+
WHEN format = "MON" OR format = "MM" OR format = "RM" OR format = "MONTH" THEN
32+
IF(EXTRACT(DAY FROM d) >= 16, DATETIME_ADD(DATETIME_TRUNC(d, MONTH), INTERVAL 1 MONTH), DATETIME_TRUNC(d, MONTH))
33+
WHEN format = "WW" THEN
34+
(
35+
WITH t AS (
36+
SELECT
37+
DATE_DIFF(d, DATE_TRUNC(d, YEAR), HOUR) AS h,
38+
CAST(24 * 7 AS int64) AS hw
39+
)
40+
SELECT
41+
DATETIME_TRUNC(DATETIME_ADD(DATE_TRUNC(d, YEAR), INTERVAL CAST((DIV(h, hw) + IF (MOD(h, hw) < hw / 2, 0, 1)) * hw AS int64) hour), DAY)
42+
FROM t
43+
)
44+
WHEN format = "IW" THEN
45+
(
46+
WITH t AS (
47+
SELECT
48+
DATE_DIFF(d, DATE_TRUNC(d, ISOYEAR), HOUR) AS h,
49+
CAST(24 * 7 AS int64) AS hw
50+
)
51+
SELECT
52+
DATETIME_TRUNC(DATETIME_ADD(DATE_TRUNC(d, ISOYEAR), INTERVAL CAST((DIV(h, hw) + IF(MOD(h, hw) < hw / 2, 0, 1)) * hw AS int64) hour), DAY)
53+
FROM t
54+
)
55+
WHEN format = "W" THEN
56+
(
57+
WITH t AS (
58+
SELECT
59+
DATE_DIFF(d, DATE_TRUNC(d, MONTH), HOUR) AS h,
60+
CAST(24 * 7 AS int64) AS hw
61+
)
62+
SELECT
63+
DATETIME_TRUNC(DATETIME_ADD(DATE_TRUNC(d, MONTH), INTERVAL CAST((DIV(h, hw) + IF (MOD(h, hw) < hw / 2, 0, 1)) * hw AS int64) hour), DAY)
64+
FROM t
65+
)
66+
WHEN format = "DDD" OR format = "DD" OR format = "J" THEN
67+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 12 HOUR), DAY)
68+
WHEN format = "DY" OR format = "D" OR format = "DAY" THEN
69+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 84 HOUR), WEEK)
70+
WHEN format = "HH24" OR format = "HH12" OR format = "HH" THEN
71+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 30 MINUTE), HOUR)
72+
WHEN format = "MI" THEN
73+
DATETIME_TRUNC(DATETIME_ADD(d, INTERVAL 30 SECOND), MINUTE)
74+
ELSE NULL
75+
END
76+
);
Lines changed: 42 additions & 0 deletions

0 commit comments

Comments
 (0)