Magnolia JCR-SQL2 order by Date - magnolia

In the JCR, I've noticed that dates are stored in the format Feb 19, 2015 12:00:00 AM. This means that when you try and order a query by a date, it doesn't seem to work:
SELECT * FROM [mgnl:pages] ORDER BY articlePublishedDate
Will return:
Apr 1, 2015 12:00:00 AM
Dec 1, 2015 12:00:00 AM
Feb 1, 2015 12:00:00 AM
Is there any way to make the ORDER BY clause act as a integer? I've tried CAST(articlePublishedDate AS LONG) but it appears my content repository doesn't like it ...

This is more issue of JCR than Magnolia , however, one may do the following for working this around.
SELECT p.* FROM [mgnl:page] AS p
WHERE p.[mgnl:lastModified] > CAST('2016-06-10T07:24:50.233Z' AS DATE)
I assume order by also should work the same way.
Cheers

Make sure articlePublishedDate node property is of type Date, not String. For example, the following JCR2 query returned the results in the correct order when executed on the website repository:
select p.* from [mgnl:page] as p order by p.[jcr:created] desc

Ended up sorting in code, as it wasn't supported by my implementation of JCR.

Related

How to convert a specific date format into a proper data type and query related records between dates?

I am learning neo4j and have a problem where a given data set I have uploaded has a weird date format which I can't query using neo4j's bult in date functions because it was uploaded as a string. The format is the following:
╒══════════════════════════╕
│"t.date" │
╞══════════════════════════╡
│"Mon 18 Feb 2019 12:18:57"│
├──────────────────────────┤
│"Mon 18 Feb 2019 12:18:57"│
└──────────────────────────┘
I have already created a node that contains date as a property and stores the dates in the above format.
How can I change this so I can query the associated node to return results BETWEEN certain dates, so for example:
MATCH (t:Text)
WHERE t.date = 'Mon 18 Feb 2019 12:18:57'
RETURN t.description;
I would need to be able to query for Texts in between certain dates for example texts written in between Mon 18 Feb 2019 12:18:57 and Mon 19 Feb 2019 12:18:57
Thank you!
There are two ways:
Change the existing date property to Neo4j 'DateTime'. Which can be easily queried. (RECOMMENDED)
Keep the date property as it is and use apoc to compare the date each time you want to query. (NOT RECOMMENDED)
You can use apoc.date.parse function from APOC Plugin to parse the date string into epoch time by specifying the SimpleDateFormat
You can use the following query to change your existing dates into Neo4j 'DateTime': (For Solution 1)
MATCH (n:Text)
WHERE n.date IS NOT NULL
SET n.date=datetime({epochmillis:apoc.date.parse(n.date, 'ms',"EEE dd MMM yyyy HH:mm:ss")})
Refer Neo4j DateTime
Note: Install APOC before running above query.
Once you convert the date string into datetime format, you can do below query to get text description when date is between Feb 18 and 19 12:18:57. Notice the letter 'T' at the middle. It means time.
MATCH (t:Text)
WHERE t.date > datetime('2019-02-18T12:18:57')
AND t.date < datetime('2019-02-19T12:18:57')
RETURN t.description;
Reference:
https://neo4j.com/docs/cypher-manual/current/functions/temporal/datetime/#functions-datetime-create-string

TO_DATE yy,yyyy gives me different results

If I run the below queries
select to_char( TO_DATE(SYSDATE-7,'DD/MM/YY') ,'year') from dual
The result is twenty seventeen
select to_char( TO_DATE(SYSDATE-7,'DD/MM/YYYY') ,'year') from dual
The result is seventeen
why don't I get twenty seventeen for the second query?
Because you are doing an unnecessary explicit conversion from string to date, which is doing an implicit conversion from date to string based on your NLS settings.
What you should be doing is just:
select to_char(sysdate - 7, 'year') from dual;
TO_CHAR(SYSDATE-7,'YEAR')
------------------------------------------
twenty seventeen
Because sysdate-7 is already a date, you should not be calling to_date() around that, with any format. As the to_date() function takes a string argument, your sysdate-7 expression has to be implicitly converted to a string first. So you are really doing:
select to_char(to_date(to_char(sysdate - 7), 'DD/MM/YYYY'), 'year') from dual;
which is using your NLS_DATE_FORMAT value for the implicit inner to_char() call, so if that is say 'DD-MON-RR' you're actually doing:
select to_char(to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY'), 'year') from dual;
To see what's going on in there you need to see what the full generated date is, so for that I'm going to change the NLS_DATE_FORMAT for the session to show the full year:
alter session set nls_date_format = 'SYYYY-MM-DD';
select sysdate - 7 as raw_date,
to_char(sysdate - 7, 'DD-MON-RR') as implicit_string,
to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YY') as implcit_yy,
to_date(to_char(sysdate - 7, 'DD-MON-RR'), 'DD/MM/YYYY') as implcit_yyyy
from dual;
RAW_DATE IMPLICIT_STRING IMPLCIT_YY IMPLCIT_YYY
----------- ------------------ ----------- -----------
2017-04-30 30-APR-17 2017-04-30 0017-04-30
Notice the different years in the last two values. The documentation has a section on format model matching. The string you are implicitly creating in the middle has a 2-digit year. When you convert the string '30-APR-17' back to a date using a YY model, it 'helpfully' assumes the current century, so the date ends up as 2017. But when you convert the same string using a YYYY model it thinks you really meant the value you passed in and so doesn't assume a century - and you passed it 17, so you end up with the year 17; that is, 0017 and not 2017. (You would also have got the answer you expected using RRRR, but it is much better to stick to YYYY and actually use 4-digit years everywhere - if you actually need to use a string at all.)
Essentially: don't rely on NLS settings or implicit conversions of dates to strings or vice versa.
In this case you don't need any conversions, so use the simpler statement at the top of this answer.
you should get 2017 for second query, not for the 1 query. Other possibility is NLS settings or session, software settings.
Apart from that you have to use 'YYYY' instead of 'YY' to get 2017

SQLite timestamp conversion function

I've inherited a SQLite DB, in it I've a TIMESTAMP field called ZDATE.
One value is 401,580,000 and I know it correspond to Sept 23rd, 2013.
I've calculated that the 0 of this field is the midnight of Jan 1st, 2001 (?).
However, I didn't find any conversion function to get a formatted date, in fact if I use date() I get:
ZDATE date(zdate)
401580000 1094776-12632211-20
Any help will be appreciated.
> select 401580000 / (julianday('2013-09-23') - julianday('2001-01-01'));
86398.4509466437
> select 60*60*24;
86400
So this timestamp appears to use seconds.
To convert it into a timestamp that SQLite can use directly, i.e., a Unix epoch timestamp, just add the appropriate offset:
> select datetime(401580000 + strftime('%s', '2001-01-01 02:00:00'), 'unixepoch');
2013-09-23 00:00:00

SQLite Group by Month

I am using SQLite Database and in one my table has field purchased_date (TEXT ,since DATE is not in SQLLite)
Now I want to run query that return me all the results where user purchased in Month of February 2012
I am storing Dates in following format
Tue Mar 27 09:38:31 BST 2012
Is it possible to run query for above date format or do I need to put in different format ?
You can use the strftime built-in function to extract the month from the stored text value and group by this.
A full list of the datetime functions can be found here http://sqlite.org/lang_datefunc.html

Possible to create a query that sorts by day of week?

Is it possible to write a SQL query that sorts data set by day of week starting from a specific day?
For example, if today is Thursday, the results are sorted from THU-FRI-SAT-...-MON-TUE-WED.
If today is Tuesday, the results would be sorted from TUE-WED-THU-...-SAT-SUN-MON.
Days are stored as integers.
Assuming you have the day of the week stored into field WD where value 1 means MON, 2 means TUE etc and SW is the "start of the week" index (again 1:MON, 2:TUE,...) then something like
CASE WHEN WD < SW THEN WD + 7 ELSE WD END
should give you a value to order by. I don't use sqlite so I'm not sure can you put it right into the ORDER BY or do you have to use it as a field and then order by that field.
in mysql: ORDER BY DATE_FORMAT(date,%w)
see: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-format
Microsoft databases suport this (not shure)
... ORDER by DATENAME ( dw , table.datefield )
Check out DATEPART:
http://www.tizag.com/sqlTutorial/sqldatepart.php

Resources