Select random row for each group

24,777
select distinct on (id) id, attribute
from like_this
order by id, random()

If you only need the attribute column:

select distinct on (id) attribute
from like_this
order by id, random()

Notice that you still need to order by id first as it is a column of the distinct on.

If you only want the distinct attributes:

select distinct attribute
from (
    select distinct on (id) attribute
    from like_this
    order by id, random()
) s
Share:
24,777
speendo
Author by

speendo

Updated on July 13, 2022

Comments

  • speendo
    speendo almost 2 years

    I have a table like this

    ID    ATTRIBUTE
     1    A
     1    A
     1    B
     1    C
     2    B
     2    C
     2    C
     3    A
     3    B
     3    C
    

    I'd like to select just one random attribute for each ID. The result therefore could look like this (although this is just one of many options

    ATTRIBUTE
    B
    C
    C
    

    This is my attempt on this problem

    SELECT
      "ATTRIBUTE"
    FROM
      (
      SELECT
        "ID",
        "ATTRIBUTE",
        row_number() OVER (PARTITION BY "ID" ORDER BY random()) rownum
      FROM
        table
      ) shuffled
    WHERE
      rownum = 1
    

    however, I don't know if this is a good solution, as I need to introduce row numbers, which is a bit cumbersome.

    Do you have a better one?

  • speendo
    speendo about 11 years
    but this would return EVERY attribute in a random order, not just one per ID, or do I misunderstand your code?
  • Clodoaldo Neto
    Clodoaldo Neto about 11 years
    @speendo The distinct on (id) makes it return one only row per id
  • Dan Oak
    Dan Oak over 7 years
    laughed like this :D
  • Roelant
    Roelant almost 7 years
    No syntax like this in mysql is there? :)
  • Adithya Sama
    Adithya Sama over 2 years
    wouldn't the result always have the same order, even though its random the first time.