Date Arithmetic: Cassandra 4 - date

The data I am loading into Cassandra contains dates(timestamp type).
I need to do calculations with these dates to calculate, for example the difference between a given date and now() or between two date(timestamp type) columns.
I tried:
SELECT x, date_1 - date_2 as age FROM y WHERE a = 'z';
I tried parentheses, the 'AS' clause and casting the timestamps to a date type, but received errors.
I also tried creating a UDF(User Defined Function):
CREATE OR REPLACE FUNCTION x.age_calc (tounixtimestamp(date_1) int, tounixtimestamp(date_2) int) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS 'return Integer.valueOf(Math.abs(tounixtimestamp(date_1) - tounixtimestamp(date_2)))';
I can see the above UDF has incorrect syntax but don't quite know how/where to fix it.
I wish for instance to get a difference in milliseconds and convert it into years or months.(the conversion part is easy, I hope)
I am sure I am close to getting there but my syntax in all examples tried is incorrect.
Web searches over a number of days have yielded no really similar examples.
I am guessing Cassandra 4 can do this.
Versions:
Cassandra Version: 4.0-beta2, cqlsh 5.0.1

The simplest way to do what you want is:
SELECT x, toUnixTimestamp(date_1) - toUnixTimestamp(date_2) as age FROM y WHERE a = 'z';

Related

Time difference between two timestamps in postgres using age is not rounding up

Trying to determine the time difference between two timestamp fields in postgres in HH24:MI:SS format, i.e.
date_started and date_completed
that have the following data:
date_started = 12/11/2021 09:11:00
date_completed = 12/11/2021 09:19:00
Using the following query:
select to_char(AGE(date_completed, date_started),'hh24:mi:ss') as "time_diff"
from my_table
returns the following value: 00:07:59
Notes: both these fields have a data type of: timestamp without timezone
My question is, why is this not actually returning 00:08:00 seeing that it is exactly, 8 minutes difference?
Solved my issue using the following:
select to_char(AGE(DATE_TRUNC('second', date_completed::timestamp), DATE_TRUNC('second', date_started::timestamp)),'hh24:mi:ss') as "time_diff"
from my_table
Reference SO: Discard milliseconds part from timestamp
Just want to also acknowledge #Bohemian for their input in assisting me to solve this issue wrt microseconds.

how to use the age() function in postgresql

I have a column in the students table called birthdate. i need to find students over the age of 12.
select ......, age(timestamp 'birthdate') as StudentAge
from students
.....
where StudentAge > 11
I dont know if thats the proper syntax or if im using the correct function for the situation
I think most of your confusion comes from unfamiliarity with Postgres's rich type system, and the syntax it uses.
In the page on date/time functions, the age function is listed with two forms. Assuming you want to compare to "today", you want the form with a single argument:
Function: age(timestamp)
Return type: interval
Description: Subtract from current_date (at midnight)
Example: age(timestamp '1957-06-13')
Result: 43 years 8 mons 3 days
So, you have a function which takes a value of type timestamp, and returns a value of type interval.
The example shows the input being specified as timestamp '1957-06-13'; this is just a way of creating a value of type timestamp from a hard-coded value - like creating an object in an object-oriented language. In your query, birthdate is not a hard-coded value, it's the name of a column, so this is not the syntax you want. If the column is of type timestamp, you can just use age(birthdate) directly; if not, you might need to convert it, e.g. age(CAST(birthdate AS timestamp)).
The output is of type interval, not a number of years, so comparing it against 12 is unlikely to do what you want. Instead, you should compare it against another interval value. Similar to the timestamp '1957-06-13' example, you can write interval '12 years' to directly create an interval value representing 12 years.
So your comparison would look like age(birthdate) >= interval '12 years'.
I don't know that tutorial you are talking about, but the documentation has the following to say about column labels:
The entries in the select list can be assigned names for subsequent processing, such as for use in an ORDER BY clause or for display by the client application.
Observe the subsequent here: The SELECT list is (logically) processed after the WHERE clause, so you cannot use column labels there.
You'll have to repeat the expression. This is in accordance with the SQL standard.
Moreover, birthdate is not a string literal, so don't quote it. And remove the timestamp.

Converting string timestamp into date

I have dates in a postgres database. The problem is they are stored in a string field and have values similar to: "1187222400000" (which would correspond to 07.08.2007).
I would like to convert them into readable dates usind some SQL to_date() expression or something similar but can't come up with the correct syntax to make it work.
There really isn't enough information here for a conclusion, so I propose this 'scientific-wild-ass-guess' to resolve your puzzle. :)
It appears this number is UNIX 'epoch time' in milliseconds. I'll show this example as if your string field had the arbitrary name, 'epoch_milli'. In postgresql you can convert it to a time stamp using this statement:
SELECT TIMESTAMP WITH TIME ZONE 'epoch' + epoch_milli * INTERVAL '1 millisecond';
or using this built-in postgresql function:
SELECT to_timestamp(epoch_milli / 1000)
either of which, for the example '1187222400000', produces the result
"2007-08-15 17:00:00-07"
You can do some of your own sleuthing with quite a few values selected similarly to this:
SELECT to_timestamp(epoch_milli/1000)::DATE
FROM (VALUES (1187222400000),(1194122400000)) AS val(epoch_milli);
"Well, bollocks, man. I just want the date." Point taken.
Simply cast the timestamp to a date to discard the excess bits:
SELECT to_timestamp(epoch_milli / 1000)::DATE
Of course its possible that this value is a conversion or is relative to some other value, hence the request for a second example data point.

MDX number of days between shell date dimension and regular date dimension

I have a shell date dimension, and a sale date dimension. Having trouble setting up a calculated measure with the difference in days between the 2 dates.
I have tried a number of things, and the calculation always seems to return an error.
mdx example is:
WITH
MEMBER [Measures].[TimeDate] AS [Date].[Day].currentmember
MEMBER [Measures].[DSODate] AS [DSO Date].[Day].currentmember
MEMBER [Measures].[DaysSinceSale] AS
DateDiff(
"d"
, [Measures].DSODate.MemberValue
, [Measures].TimeDate.MemberValue
)
Select
{[Measures].[DaysSinceSale]} ON COLUMNS,
{[Date].[Day].members} ON ROWS
from [Receivables];
I have tried using DateDiff, and tried just subtracting the 2 dates.
Assuming it may have something to do with the 2 date dimensions being of different hierarchies, but i am not really sure how to handle that.
MDX Results
Date conversions can be tricky in mdx so maybe initially try the following simple approach:
WITH
MEMBER [Measures].[TimeDate] AS [Date].[Day].currentmember
MEMBER [Measures].[DSODate] AS [DSO Date].[Day].currentmember
MEMBER [Measures].[DaysSinceSale] AS
DateDiff(
"d"
, VBA!CDate([Measures].DSODate.MemberValue)
, VBA!CDate([Measures].TimeDate.MemberValue)
)
Select
{[Measures].[DaysSinceSale]} ON COLUMNS,
{[Date].[Day].members} ON ROWS
from [Receivables];
Otherwise you might need to use the key and an approach similar to this:
MDX - Converting Member Value to CDate
I found a way to get this to work ...
Main issue was that i didn't have a crossjoin, like whytheq mentioned.
I also didn't need the custom Measures declared at the top.
The other adjustment i made was to utilize the DateKey in the date calculation. That seemed to work in all my tests, and improved performance quite a bit.
WITH
MEMBER [Measures].[DaysSinceSale] AS
[Date].[DateKey].CurrentMember.MemberValue - [DSO Date].[DateKey].CurrentMember.MemberValue
Select
{[Measures].[DaysSinceSale]} ON COLUMNS,
{[Date].[DateKey].Members * [DSO Date].[DateKey].members} ON ROWS
from [Receivables];
If you see any issues that may arise with using DateKey let me know. For what i am doing that seemed to pull back the correct date value, and allowed me to find the difference between dates without using a datediff function.

How to convert a 5 digit INT to date

I apologise if this question has been asked but I cannot find an answer that quite fits.
I have a database with dates stored as 5 digit integers. I can covert these to datetime, however the dates are showing in the future.
For example,
select convert(datetime,StartDate,103)
from dpm.Schedule
where ScheduleID like 50003;
Gives the results of
2107-05-31 00:00:00:000 but this date should actually be 26/05/2008.
I am pretty new to T-SQL and have looked for sometime to find the answer to this but I am reaching the end of my sanity.
We cannot answer because you are doing a lot of confusion. To start 5003 is the Id of the record and [StartDate] is the value you are trying to convert.
Also drop using operator LIKE in the Id
Example:
select convert(datetime,50003,103)
returns:
2036-11-26 00:00:00.000
but you are trying to convert the value returned by
select StartDate
from dpm.Schedule
where ScheduleID = 50003;
Please edit your question and show us a nice example using SQL Fiddle