PostgreSQL: how do I query over a column with a custom range?
The range type would allow best performance and simple queries.

If you have some string values like k and Pre-K mixed with numeric values, just create a grade table with a rank value (an integer value representing actual sort order):

CREATE TABLE grade(
   grade text PRIMARY KEY
  ,grade_int UNIQUE int NOT NULL
);


Your numeric grades can conveniently be assigned the same grade_value, other grades get integer values according to their rank.

You might write a simple function to convert ranges with your original string values to their integer representations on the fly ...
And vice-versa to display your grades_served column where needed.

Convert grades_served to an int4range type.
Using the overlap operator &amp;&amp;, your query for a range of grades can then simply be:

SELECT * FROM tbl WHERE grades_served &amp;&amp; '[1,4]'::int4range;


Or, for a single grade, the "contains element" operator @&gt;

SELECT * FROM tbl WHERE grades_served @&gt; -1;


Index

If your table is not very small I suggest you create a GiST index to support that (and so does the manual).

CREATE INDEX tbl_grades_served_idx ON tbl USING gist (grades_served);