This function works and despite the convoluted construction it is pretty
fast, takes about 0.5 sec to convert one field in about 25000 rows.
I thought I can speed it up by replacing all the SQLite functions that
produce a literal by a VB variable. Indeed with this I can get it down to
about 0.3 secs. Does this mean that SQLite recalculates these functions
multiple times for every row? I suppose it does and in a way it makes sense
as 'now' changes over time.
In case any VB user is interested in this:

Function CurrentDateISO8601() As String

  Dim lCY As Long
  Dim lCM As Long
  Dim lCD As Long
  Dim strZeroMonth As String
  Dim strZeroDay As String

  lCY = Year(Date)
  lCM = Month(Date)
  lCD = Day(Date)

  If lCM < 10 Then
    strZeroMonth = "0"
  End If

  If lCD < 10 Then
    strZeroDay = "0"
  End If

  CurrentDateISO8601 = "'" & lCY & "-" & _
                       strZeroMonth & lCM & "-" & _
                       strZeroDay & lCD & "'"

End Function

Function ISO8601Date2AgeInMonths(strField As String, _
                                 Optional strAlias As String) As String

  Dim strAS As String
  Dim strCDate As String
  Dim lCM As Long
  Dim lCD As Long
  Dim strCY As String
  Dim strCM As String
  Dim strCD As String

  lCM = Month(Date)
  lCD = Day(Date)

  strCY = "'" & CStr(Year(Date)) & "'"

  If lCM < 10 Then
    strCM = "'0" & CStr(lCM) & "'"
  Else
    strCM = "'" & CStr(lCM) & "'"
  End If

  If lCD < 10 Then
    strCD = "'0" & CStr(lCD) & "'"
  Else
    strCD = "'" & CStr(lCD) & "'"
  End If

  strCDate = CurrentDateISO8601()

  If Len(strAlias) > 0 Then
    strAS = " AS "
  End If

  ISO8601Date2AgeInMonths = _
  "case when " & strCDate & " >= " & _
  "date(" & strField & ", '+' || " & strCY & " - " & _
  "strftime('%Y', " & strField & ") || ' years') then " & _
  "case when " & strCD & " < strftime('%d', " & strField & ") then " & _
  "((" & strCY & " - strftime('%Y', " & strField & ")) * 12 + " & _
  "(" & strCM & " - strftime('%m', " & strField & "))) - 1 " & _
  "else " & _
  "((" & strCY & " - strftime('%Y', " & strField & ")) * 12 + " & _
  "(" & strCM & " - strftime('%m', " & strField & "))) - 0 " & _
  "end " & _
  "else " & _
  "case when " & strCD & " < strftime('%d', " & strField & ") then " & _
  "((" & strCY & " - strftime('%Y', " & strField & ") - 1) * 12 + " & _
  "(" & strCM & " + (12 - strftime('%m', " & strField & ")))) - 1 " & _
  "else " & _
  "((" & strCY & " - strftime('%Y', " & strField & ") - 1) * 12 + " & _
  "(" & strCM & " + (12 - strftime('%m', " & strField & ")))) - 0 " & _
  "End " & _
  "End" & strAS & strAlias

End Function


RBS


-----Original Message-----
From: RB Smissaert [mailto:[EMAIL PROTECTED] 
Sent: 01 June 2007 23:45
To: sqlite-users@sqlite.org
Subject: RE: [sqlite] Age calculation on literal

Got the syntax right, but not the logic.
I believe this (VB) function will now get the right SQL to get the age in
months:

Function ISO8601Date2AgeInMonths(strField As String, _
                                 Optional strAlias As String) As String

  Dim strAS As String

  If Len(strAlias) > 0 Then
    strAS = " AS "
  End If

  ISO8601Date2AgeInMonths = "case when date('now') >= " & _
                            "date(" & strField & ", '+' || (strftime('%Y',
'now') - " & _
                            "strftime('%Y', " & strField & ")) || ' years')
then " & _
                            "case when strftime('%d', 'now') <
strftime('%d', " & strField & ") then " & _
                            "((strftime('%Y', 'now') - strftime('%Y', " &
strField & ")) * 12 + " & _
                            "(strftime('%m', 'now') - strftime('%m', " &
strField & "))) - 1 " & _
                            "else " & _
                            "((strftime('%Y', 'now') - strftime('%Y', " &
strField & ")) * 12 + " & _
                            "(strftime('%m', 'now') - strftime('%m', " &
strField & "))) - 0 " & _
                            "end " & _
                            "else " & _
                            "case when " & _
                            "strftime('%d', 'now') < strftime('%d', " &
strField & ") " & _
                            "then " & _
                            "(strftime('%Y', 'now') - strftime('%Y', " &
strField & ") - 1) * 12 + " & _
                            "(strftime('%m', 'now') + (12 - strftime('%m', "
& strField & "))) - 1 " & _
                            "else " & _
                            "((strftime('%Y', 'now') - strftime('%Y', " &
strField & ") - 1) * 12 + " & _
                            "(strftime('%m', 'now') + (12 - strftime('%m', "
& strField & ")))) - 0 " & _
                            "End " & _
                            "End" & strAS & strAlias

End Function


RBS


-----Original Message-----
From: RB Smissaert [mailto:[EMAIL PROTECTED] 
Sent: 01 June 2007 21:46
To: sqlite-users@sqlite.org
Subject: RE: [sqlite] Age calculation on literal

Got this now, after correcting the brackets:

SELECT
case when
    date('2006-10-14', '+' || (strftime('%Y', 'now') - strftime('%Y', '2006-
10-14')) || ' years') <= date('now') then
    case when
        strftime('%d', 'now') > strftime('%d', '2006-10-14')
    then
        ((strftime('%Y', 'now') - strftime('%Y', '2006-10-14')) * 12 +
        (strftime('%m', 'now') - strftime('%m', '2006-10-14'))) - 1 
    else 
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14')) * 12 +
        (strftime('%m', 'now') - strftime('%m', '2006-10-14'))
    end 
else 
    case when
        strftime('%d', 'now') > strftime('%d', '2006-10-14')
    then
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14') - 1) * 12 +
        (strftime('%m', 'now') +
        (12 - strftime('%m', '2006-10-14'))) - 1 
    else 
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14') - 1) * 12 +
        (strftime('%m', 'now') + (12 - strftime('%m', '2006-10-14')))
    end
end


RBS


-----Original Message-----
From: Dennis Cote [mailto:[EMAIL PROTECTED] 
Sent: 01 June 2007 19:53
To: sqlite-users@sqlite.org
Subject: Re: [sqlite] Age calculation on literal

On 6/1/07, RB Smissaert <[EMAIL PROTECTED]> wrote:
>
> Got this nearly worked out now, but somehow I can't get the nested case
> when
> syntax right:
>
> SELECT
> case
> when
> date('2006-10-14', '+' || (strftime('%Y', 'now') - strftime('%Y',
> '2006-10-14')) || ' years') <= date('now')
> then
> case when
> strftime('%d', 'now') > strftime('%d', '2006-10-14')
> then
> ((strftime('%Y', 'now') - strftime('%Y', '2006-10-14')) * 12 +
> (strftime('%m', 'now') - strftime('%m', '2006-10-14')) - 1
> else
> (strftime('%Y', 'now') - strftime('%Y', '2006-10-14'))) * 12 +



You have an extra closing bracket in the line above.


(strftime('%m', 'now') - strftime('%m', '2006-10-14'))
> end
> else
> case when
> strftime('%d', 'now') > strftime('%d', '2006-10-14')
> then
> ((strftime('%Y', 'now') - strftime('%Y', '2006-10-14') -1)   * 12 +
> (strftime('%m', 'now') +
> (12 - strftime('%m', '2006-10-14')))) -1
> else
> (strftime('%Y', 'now') - strftime('%Y', '2006-10-14') -1)  * 12 +
> (strftime('%m', 'now') +
> (12 - strftime('%m', '2006-10-14')))
> end
> end
>
> It will give me an error (from my VB wrapper) syntax error near else.
> Any idea what is wrong here?


Try this instead, I find the extra indentation makes it easier to see what
you are doing.

SELECT
case when
    date('2006-10-14', '+' || (strftime('%Y', 'now') - strftime('%Y',
    '2006-10-14')) || ' years') <= date('now')
then
    case when
        strftime('%d', 'now') > strftime('%d', '2006-10-14')
    then
        ((strftime('%Y', 'now') - strftime('%Y', '2006-10-14')) * 12 +
        (strftime('%m', 'now') - strftime('%m', '2006-10-14')) - 1
    else
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14')) * 12 +
        (strftime('%m', 'now') - strftime('%m', '2006-10-14'))
    end
else
    case when
        strftime('%d', 'now') > strftime('%d', '2006-10-14')
    then
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14') - 1) * 12 +
        (strftime('%m', 'now') +
        (12 - strftime('%m', '2006-10-14')))) -1
    else
        (strftime('%Y', 'now') - strftime('%Y', '2006-10-14') - 1) * 12 +
        (strftime('%m', 'now') + (12 - strftime('%m', '2006-10-14')))
    end
end

HTH
Dennis Cote



----------------------------------------------------------------------------
-
To unsubscribe, send email to [EMAIL PROTECTED]
----------------------------------------------------------------------------
-




----------------------------------------------------------------------------
-
To unsubscribe, send email to [EMAIL PROTECTED]
----------------------------------------------------------------------------
-




-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to