On 2018/08/02 10:29 PM, Csányi Pál wrote:
Hi,

I just want to know why the following SQLite query does not work as I expected?

WITH RECURSIVE dates(dateD) AS ( VALUES('2015-10-03') UNION ALL SELECT
date(dateD, '+1 year') FROM dates WHERE date(dateD) <=
date('2016-11-01') ) SELECT max(dateD), count(dateD) FROM dates;
2017-10-03|3
which is not what I am expecting.

I am expecting the followings:
1. the query add to the date('2015-10-03') 1 year which is '2016-10-03'
2. then it compares the two dates: 2016-10-03 with 2016-10-03
3. because 2016-10-03 = 2016-10-03 it count 1
4. then add to the result date 2016-10-03 once again 1 year which is 2017-10-03
5. then it compares the two dates: 2017-10-03 with 2016-10-03
6. because 2017-10-03 > 2016-10-03 it does not count 2
7. it should gives the following result:
2016-10-03|1

What am I doing wrong here?


When the recursive Query starts up, the first value that it outputs is given by the very first part of the query, namely: VALUES('2015-10-03')
So on the first iteration, it will produce one row like this:
'2015-10-03'
regardless of the rest of the Query. This row is pushed into the recursion buffer.

After that it then reads a row from the recursion buffer and checks (within the WHERE clause) whether the value in it (namely: '2015-10-03') is <= '2016-11-01', and finds that it definitely IS less, so continues to produce the another line of output.

The output created is that date from the buffer (2015-10-03) which is put through the given calculation: date(dateD, '+1 year') to give:
'2016-10-03'

It then continues to push that next row into the recursion buffer and next reads again from it and again checks if it (2016-10-03) is <= than 2016-11-01, which again it is... so it continues to produce the next output row, which after calculation becomes:
'2017-10-03'

It then continues to push that again into the buffer and again read it and again checks if it (2017-10-03) is less than 2016-11-01, which THIS TIME, it isn't... so it stops right there.

So in the end, it has produced 3 output rows namely:
'2015-10-03'
'2016-10-03'
'2017-10-03'

Which is exactly what you've asked for.

Note: The first part of the query will ALWAYS reach the output buffer, even if it isn't a recursive query, and the UNION is NOT specified, you will get at least the '2015-10-03' value. Note: When comparing in the WHERE clause, you do not compare the newly calculated value (date(xxx, +1 year)), but indeed you compare the before-calculated value, i.e. the previous value in the buffer (the same as how your calculation is done on the PREVIOUS value in the buffer to yield the new date with.

I hope that helps to make sense.

Cheers,
Ryan


_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to