0

I have a database table with a grade_range column, the rows of this column contain duplicate values all separated by a comma (like a list).

grade_range
"Pre-K, Pre-K, Pre-K"
"Pre-K, K-9, K-9"
"Pre-K, K-7, 9-12"
"Pre-K, K-7, K-7"
"Pre-K, K-6"
"Pre-K, K-5"

I want to update these records so that I am only left with the unique values in the rows of this column, like this

grade_range
"Pre-K"
"Pre-K, K-9"
"Pre-K, K-7, 9-12"
"Pre-K, K-7"
"Pre-K, K-6"
"Pre-K, K-5"

Distinct column values can be easily selected in SQL using -

SELECT DISTINCT grade_range FROM dev.school

but, I am not sure how to select/update distinct values inside a row-cell. One way I thought of doing was to manipulate this data in Excel and then updating records using an UPDATE statement based on the same sids

Any suggestion on accomplishing this in SQL?

hky404
  • 1,039
  • 3
  • 17
  • 35

2 Answers2

1

Use this function to convert the comma seperated values to rows then use distince then concatenate them again

ALTER FUNCTION [dbo].[Split]
    (
        @List varchar(max),
        @SplitOn nvarchar(5)
    )  
    RETURNS @RtnValue table 
    (

        ID int identity(1,1),
        Val varchar(max)
    ) 
    AS  
    BEGIN 
        While (Charindex(@SplitOn,@List)>0)
        Begin

            Insert Into @RtnValue (Val)
            Select 
                Val = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))

            Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
        End

        Insert Into @RtnValue (Val)
        Select Value = ltrim(rtrim(@List))

        Return
    END
asmgx
  • 7,328
  • 15
  • 82
  • 143
1

1st. Create a function to distinct an array

Open psql. Inside psql type \ef. Replace the content with this function:

CREATE OR REPLACE FUNCTION public.array_unique(arr anyarray)
RETURNS anyarray 
LANGUAGE sql AS 
$function$
  select array( select distinct unnest($1) )
$function$

2nd. Play the game

Assuming each element constantly divided by comma and space. We can split per rows into array format, distinct it with previous function, then convert it back to a string.

SELECT 
   array_to_string(array_unique(regexp_split_to_array(grade, E', ')), ',') as grade_distinct, 
   grade 
FROM 
   your_table;

Result

localhost:5432 user@database=# 
SELECT 
   array_to_string(array_unique(regexp_split_to_array(grade, E', ')), ',') as grade_distinct, 
   grade 
FROM 
   tmp_stack_overflow;

 grade_distinct |        grade        
----------------+---------------------
 Pre-K          | Pre-K, Pre-K, Pre-K
 Pre-K,K-9      | Pre-K, K-9, K-9
 Pre-K,K-7,9-12 | Pre-K, K-7, 9-12
 Pre-K,K-7      | Pre-K, K-7, K-7
 K-6,Pre-K      | Pre-K, K-6
 K-5,Pre-K      | Pre-K, K-5
(6 rows)
Brain90
  • 1,551
  • 18
  • 21