I am struggling to find a working query in SQLite, that will return my records in their upcoming birthday along with the number of days it will happen
CREATE TABLE contact_birthday ('contact_id' varchar,'data1' varchar,'display_name' varchar)
data1
holds the birthday in YYYY-MM-DD format
Something like:
"1986-06-28","Angel","0"
"1979-06-29","Bea","1"
"1984-07-02","John","4"
"1984-06-26","Mark","364"
I've found some other results but they are working for MySQL, or SQL Server not in SQLite.
How would be the quer开发者_运维知识库y in SQLite without user defined functions?
I got it to work using julianday (the only way to get a 'day' count AFAIK)
select name,
julianday(strftime('%Y', 'now')||strftime('-%m-%d', data1))-julianday('now') as birthday
from foo
where birthday between -1 and 30;
My result:
Angel|-0.479438499547541
Bea|0.520561488810927
John|3.52056147716939
Quick explanation:
julianday(strftime('%Y', 'now')
<- this pulls the current year so that julianday for data1 doesn't consider years from the 80's
||strftime('-%m-%d', data1))
<- this concatenates the month/day for the actual birthday to the current year
where birthday between -1 and 30;
<- the -1 ensures you will see results all the way up through 'today'. The 30 is the maximum amount of days you want to see in advance.
Edit 1:
Here's a modification that uses seconds since 1970 epoch rather than julian day:
select name,
(strftime('%s',strftime('%Y', 'now')||strftime('-%m-%d', data1))-strftime('%s','now'))/86400.0 as birthday
from foo
where birthday between -1 and 30
order by birthday;
Result:
Angel|-0.487118055555556
Bea|0.512881944444445
John|3.51288194444444
Edit 2: [Pentium10]
includes proper localtime
select data1,display_name,
(strftime('%s',strftime('%Y', 'now','localtime')||strftime('-%m-%d', data1))-strftime('%s','now','localtime'))/86400.0 as birthday
from contact_birthday
order by birthday asc
Edit 3: [Pentium10]
includes the order by if from today to next year this time are exactly 365 days
** still needs the dynamic calculation of 365 day, as that can be 366 for leap years
select data1,display_name,
((strftime('%s',strftime('%Y', 'now','localtime')||strftime('-%m-%d', data1))-strftime('%s','now','localtime'))/86400.0+1+365) % 365 as birthday
from contact_birthday
order by birthday asc
Edit 4: [Matt]
This actually might work for you:
select data1,name,
365-(strftime('%s',strftime('%Y', 'now', '+1 year', 'localtime')||strftime('-%m-%d', data1))-strftime('%s','now','localtime'))/86400.0 as birthday
from foo
order by birthday asc
Edit 5: [Pentium10]
THE ANSWER
select data1,display_name,
((strftime('%s',strftime('%Y', 'now','localtime')||strftime('-%m-%d', data1))-strftime('%s','now','localtime'))/86400.0+1+((strftime('%s','now', 'localtime','+1 year')-strftime('%s','now', 'localtime'))/86400.0)) % ((strftime('%s','now', 'localtime','+1 year')-strftime('%s','now', 'localtime'))/86400.0) as indays
from contact_birthday
order by indays asc
Result:
1984-07-02|John|-3.65773148148151
1979-06-29|Bea|-0.657731481481505
1986-06-28|Angel|0.342268518518495
1984-06-26|Mark|2.34226851851849
1987-02-16|Matt|132.342268518519
So birthdays that are coming up in the current year will be negative (e.g. John's is 3 days in the FUTURE), birthdays that have already passed this year will be positive.
This should allow for the correct ordering.
I don't have SQLLite available to test, but this should do the trick...
SELECT JULIANDAY('NOW') - JULIANDAY(data1) FROM contact_birthday ORDER BY JULIANDAY('NOW') - JULIANDAY(data1)
You could also use the STRFTIME function, but I find the JULIANDAY function to be more readable.
精彩评论