Search code examples
sqliteandroid-sqlite

SQLite convert single row to multiple rows


SQLite
I want to convert single row value seperate by ',' to multiple rows

Example :

Single_Row

6,7,8,9,10,11,12,13,14,15,16

Result must be :

MultipleRows

6
7
8
9
10
12
13
14
15
16

I tried doing it with substr function but getting unexpected result

select 
 numbers.n,
substr(CbahiHSSpecialtyUnits.units,numbers.n,1) 
from
  numbers inner join CbahiHSSpecialtyUnits
  on  LENGTH(CbahiHSSpecialtyUnits.units)
     - LENGTH(REPLACE(CbahiHSSpecialtyUnits.units, ',', ''))>=numbers.n-1
  WHERE HsSubStandardID=22 and SpecialtyID=2 and  numbers.n>0
  order by numbers.n;

enter image description here

One good thing is I'm getting number of rows correct.. But the values that should be separated is wrong .. Please note numbers table is I have created for indexing purpose, with the help of this post. SQL split values to multiple rows


Solution

  • You can do it with a recursive CTE:

    WITH cte AS (
      SELECT SUBSTR(Units, 1, INSTR(Units || ',', ',') - 1) col,
             SUBSTR(Units, INSTR(Units || ',', ',') + 1) value
      FROM CbahiHSSpecialtyUnits
      WHERE HsSubStandardID=22 AND SpecialtyID = 2
      UNION ALL
      SELECT SUBSTR(value, 1, INSTR(value || ',', ',') - 1),
             SUBSTR(value, INSTR(value || ',', ',') + 1)
      FROM cte
      WHERE LENGTH(value) > 0
    )
    SELECT col 
    FROM cte
    WHERE col + 0 > 0
    

    Or, if you know the upper limit of the numbers is, say 20 and there are no duplicates among the numbers:

    WITH cte AS (SELECT 1 col UNION ALL SELECT col + 1 FROM cte WHERE col < 20)
    SELECT c.col 
    FROM cte c INNER JOIN CbahiHSSpecialtyUnits u
    ON ',' || u.Units || ',' LIKE '%,' || c.col || ',%'
    WHERE HsSubStandardID=22 AND SpecialtyID = 2
    

    See the demo.
    Results:

    col
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16