## Syntax ```mermaid %%{init: { 'theme': 'base', 'flowchart': { 'padding': '7', 'nodeSpacing': '20', 'rankSpacing': '20' }, 'themeVariables': { 'fontSize': '11px', 'fontFamily': 'Arial' } }}%% flowchart TD ngramTableSpec_start((START)) ngramTableSpec_start --> ngramTableSpec_0_0["NGRAMTABLE("]:::quoted ngramTableSpec_0_0 --> ngramTableSpec_0_2[<a href="Invantive UniversalSQL/Grammar/Expression" class="internal-link">expression</a>] ngramTableSpec_0_2 --> ngramTableSpec_0_3[","]:::quoted ngramTableSpec_0_3 --> ngramTableSpec_0_4[<a href="Invantive UniversalSQL/Grammar/Expression" class="internal-link">expression</a>] ngramTableSpec_0_4 --> ngramTableSpec_0_5[")"]:::quoted ngramTableSpec_0_2 --> ngramTableSpec_0_5 ngramTableSpec_0_5 --> ngramTableSpec_end((END)) ``` ## Purpose Cuts a text into runs of n characters and returns one row per run. It is the table form of [[Invantive UniversalSQL/Grammar/SQL Functions/NGRAM_DICE|NGRAM_DICE]]: that function answers how many runs two values share, this one shows the runs themselves, so that near duplicates over a large table can be found with a join instead of with a comparison of every value against every other. Parameters: - Input: the text to cut into runs. - Size: the length of a run, at least one. Three when it is left out, which makes the runs the same as those of [[Invantive UniversalSQL/Grammar/SQL Functions/TRIGRAM_DICE|TRIGRAM_DICE]]. Returns: a number of rows with two columns. `gram` holds the run and `position` holds where it starts in the text, counted from one. The text is cut as it stands and nothing is folded, which is what [[Invantive UniversalSQL/Grammar/SQL Functions/NGRAM_DICE|NGRAM_DICE]] does with the same text, so the rows of this function are the set that coefficient counts. A caller who wants case folded away writes `lower()` around the argument. A run which occurs more than once yields one row, since a coefficient is over the set of runs, and a text shorter than the run asked for yields one row holding the whole text. ## Examples The following example cuts a value into runs of two characters: ```sql select gram , position from ngramtable('abcd', 2) order by position gram position ---- -------- ab 1 bc 2 cd 3 ``` The following example finds the resource codes of an application whose English texts share at least half of their runs of three characters with a given text, without comparing that text to every row: ```sql select tln.tln_resource_code , count(*) shared from ngramtable('The license key is invalid.') asked join itgen_translations_v tln on tln.apn_code = 'repos/itgen/trunk' and tln.lge_code = 'en' join ngramtable(tln.tln_text) found on found.gram = asked.gram group by tln.tln_resource_code having count(*) >= 10 order by count(*) desc ```