1

I have a field in my database which has a long list of strings separated by commas. Here are few row examples:

HAB
DHAB,RAB,DAB
HAB,RAB,DAB
RAB,HAB, 
RAB,HAB,DAB

My query has the following condition:

WHERE description LIKE '%HAB%'

But it returns the second row which has 'DHAB'.
Can it be done using regex with the WHERE statement so that I only get entries which have 'HAB' in the list (one string) and not the entries with 'DHAB'?

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
ooo
  • 673
  • 3
  • 16

2 Answers2

1

You may use

WHERE description ~ '(^|,)HAB($|,)'

The regex matches

  • (^|,) - start of string or a ,
  • HAB - literal substring
  • ($|,) - end of string or ,

See the online regex demo.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
1

Regular expressions are powerful and versatile, but also expensive. Consider a different approach: transform the list to an actual array with string_to_array() and then:

WHERE 'HAB' = ANY (string_to_array(description, ',')

Or:

WHERE  string_to_array(description, ',') @> '{HAB}'

db<>fiddle here

The latter can be supported with a GIN index, which makes it faster by orders of magnitude for big tables.

CREATE INDEX ON tbl USING gin (string_to_array(description, ','));

Related:

Or consider a normalized DB design replacing the comma-separated values with a 1:n relationship. Related:

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228