I have a timestamp
column in a Cassandra table
, how do i get the day of week
from the timestamp column using cql?
2 Answers
There isn't support out of the box for this but
If using the CQL is a must you can have a look at the User Defined Functions:
http://cassandra.apache.org/doc/latest/cql/functions.html
http://www.datastax.com/dev/blog/user-defined-functions-in-cassandra-3-0
http://docs.datastax.com/en//cql/latest/cql/cql_using/useCreateUDF.html
Then you could use something as simple as:
How to determine day of week by passing specific date?
or even something like
Aggregation with Group By date in Spark SQL
And then you have a UDF that gives you day of the week when you are working with a dates.

- 1
- 1

- 2,071
- 1
- 14
- 26
Maybe this answer will be helpful for some one still looking for an answer in 2022. You can create an user defined function:
CREATE OR REPLACE FUNCTION DOW(
input_date_string varchar,
date_pattern varchar
)
CALLED ON NULL INPUT
RETURNS int
LANGUAGE java AS
'
int ret = -1;
try {
ret = java.time.LocalDate.parse(input_date_string, java.time.format.DateTimeFormatter.ofPattern(date_pattern))
.getDayOfWeek()
.getValue();
} catch (java.lang.Exception ex) {
// error, do nothing here and -1 will be returned
}
return ret;
';
Test
cqlsh:store> create table testdate(key int PRIMARY KEY , date_string varchar );
... insert some date_strings ...
INSERT INTO testdate (key , date_string ) VALUES ( 9, '2022-11-22');
...
cqlsh:store> select date_string, dow(date_string, 'yyyy-MM-dd') from testdate;
date_string | store.dow(date_string, 'yyyy-MM-dd')
-------------+--------------------------------------
50/11/2022 | -1
2022-11-23 | 3
19/11/2024 | -1
2022-11-21 | 1
19/11/2023 | -1
19/11/20249 | -1
2022-11-20 | 7
50/aa/2022 | -1
2022-11-22 | 2
19/11/2024 | -1
Similar function with timestamp argument
CREATE OR REPLACE FUNCTION DOW_TS(
input_date_time timestamp,
zone_id varchar
)
CALLED ON NULL INPUT
RETURNS int
LANGUAGE java AS
'
int ret = -1;
try {
ret = input_date_time.toInstant().atZone(java.time.ZoneId.of(zone_id)).toOffsetDateTime()
.getDayOfWeek()
.getValue();
} catch (java.lang.Exception ex) {
// error, do nothing here and -1 will be returned
}
return ret;
';
Test
cqlsh:store> select id, dt, dow_ts(dt, 'UTC'), dow_ts(dt,'WHAT') from testdt;
id | dt | store.dow_ts(dt, 'UTC') | store.dow_ts(dt, 'WHAT')
----+---------------------------------+-------------------------+--------------------------
1 | 2022-11-19 14:30:47.420000+0000 | 6 | -1
Above functions had been tested with below cassandra's setup:
INFO [main] 2022-11-19 12:25:47,004 CassandraDaemon.java:632 - JVM vendor/version: OpenJDK 64-Bit Server VM/11.0.17
INFO [main] 2022-11-19 12:25:50,737 StorageService.java:736 - Cassandra version: 4.0.7
INFO [main] 2022-11-19 12:25:50,738 StorageService.java:737 - CQL version: 3.4.5
References:
- https://docs.datastax.com/en/dse/6.8/cql/cql/cql_using/useCreateUDF.html
- https://cassandra.apache.org/_/quickstart.html
Hint: you should ensure to set "enable_user_defined_functions: true" in /etc/cassandra/cassandra.yaml. With docker option above (https://cassandra.apache.org/_/quickstart.html), you do a quick hack as below
$ docker run --rm -d --name cassandra --hostname cassandra --network cassandra cassandra
$ docker cp cassandra:/etc/cassandra/cassandra.yaml .
Use your favorite editor to change "enable_user_defined_functions: false" to "enable_user_defined_functions: true" in "$(pwd)"/cassandra.yaml
$ docker run --rm -d --name cassandra --hostname cassandra --network cassandra --mount type=bind,source="$(pwd)"/cassandra.yaml,target=/etc/cassandra/cassandra.yaml cassandra
If you have very old cassandra version, which does not support java8 then maybe below altenative would work (see https://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week)
CREATE OR REPLACE FUNCTION DOW_Tomohiko_Sakamoto(
input_date_time timestamp
)
CALLED ON NULL INPUT
RETURNS int
LANGUAGE java AS
'
int y = input_date_time.getYear() + 1900;
int m = input_date_time.getMonth() + 1;
int d = input_date_time.getDate();
int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
if (m < 3) {
y -= 1;
}
int ret = (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
if (ret == 0) {
ret = 7;
}
return ret;
';
TEST
cqlsh:store> insert into data(id, dt ) VALUES (2, '2022-11-19 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (3, '2022-11-21 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (4, '2022-11-23 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (5, '2022-11-24 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (7, '2022-11-25 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (8, '2022-11-26 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (9, '2022-11-27 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (10, '2022-11-28 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (11, '2020-02-29 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (12, '2020-02-30 00:00:00+0000');
cqlsh:store> insert into data(id, dt ) VALUES (13, '2020-02-31 00:00:00+0000');
cqlsh:store> select id, dt, dow_ts(dt,'UTC'), DOW_Tomohiko_Sakamoto(dt) from data;
id | dt | store.dow_ts(dt, 'UTC') | store.dow_tomohiko_sakamoto(dt)
----+---------------------------------+-------------------------+---------------------------------
5 | 2022-11-24 00:00:00.000000+0000 | 4 | 4
10 | 2022-11-28 00:00:00.000000+0000 | 1 | 1
13 | 2020-02-29 00:00:00.000000+0000 | 6 | 6
11 | 2020-02-29 00:00:00.000000+0000 | 6 | 6
1 | 2022-11-20 17:43:28.568000+0000 | 7 | 7
8 | 2022-11-26 00:00:00.000000+0000 | 6 | 6
2 | 2022-11-19 00:00:00.000000+0000 | 6 | 6
4 | 2022-11-23 00:00:00.000000+0000 | 3 | 3
7 | 2022-11-25 00:00:00.000000+0000 | 5 | 5
9 | 2022-11-27 00:00:00.000000+0000 | 7 | 7
12 | 2020-02-29 00:00:00.000000+0000 | 6 | 6
3 | 2022-11-21 00:00:00.000000+0000 | 1 | 1

- 106
- 3