FINDNTH: from Tableau to SQL

Returns the position of a requested substring occurrence. Below, 8 sample rows go through the calculation and through the SQL, and both return the same numbers.

Calculated field

FINDNTH([label], 'e', 2)

Sample data

labelquantityamountflag
cedar cedar 6512.8True
ORCHID-west66-7.6False
maple-east670null
willow north6825.3True
birch-birch694.9False
pine/south70-1.2null
ash719True
nullnullnullnull

The same calculation as SQL

SELECT CASE WHEN strpos(label,'e')=0 THEN 0 WHEN strpos(substr(label,strpos(label,'e')+1),'e')=0 THEN 0 ELSE strpos(label,'e')+strpos(substr(label,strpos(label,'e')+1),'e') END AS result FROM input

Runs the example above.

Result

result
10
0
7
0
0
0
0
null

Same rows from the calculation and from the SQL in DuckDB.

Where a naive translation goes wrong

  • Replacing FINDNTH with strpos(label,'e') changes the shown values or null handling.

    Naive SQL

    SELECT strpos(label,'e') AS result FROM input
    result
    4
    9
    5
    0
    0
    4
    0
    null

    Matches the calculation

    SELECT CASE WHEN strpos(label,'e')=0 THEN 0 WHEN strpos(substr(label,strpos(label,'e')+1),'e')=0 THEN 0 ELSE strpos(label,'e')+strpos(substr(label,strpos(label,'e')+1),'e') END AS result FROM input
    result
    10
    0
    7
    0
    0
    0
    0
    null

Signature

FINDNTH(string, string, occurrence)