PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

ORDINA PER colonne che a volte sono vuote utilizzando Active Record &Rails

Stai riscontrando un problema con le lettere maiuscole:i tuoi nomi sono tutti in maiuscolo, ma le e-mail sono minuscole e, con la maggior parte delle regole di confronto, le lettere maiuscole vengono prima delle minuscole. Dai un'occhiata a questo banale esempio:

#= select * from (values ('b'), ('B'), ('a'), ('A')) t (letter);
 letter
--------
 b
 B
 a
 A
#= select * from (values ('b'), ('B'), ('a'), ('A')) t (letter) order by letter;
 letter
--------
 A
 B
 a
 b

Quindi la tua query funziona perfettamente, è solo che [email protected] ordina dopo Josh . Per evitare ciò, puoi ordinare in base al valore minuscolo. Ecco una versione semplice dei dati che hai:

#= select * from volunteers;
 first_name | last_name |       email
------------+-----------+--------------------
 Josh       | Broger    | [email protected]
 Josh       | Kenton    | [email protected]
 ∅          | ∅         | [email protected]
 Josh       | Broger    | [email protected]
 Alex       | Diego     | [email protected]

Quindi per ordinare usando il coalesce stai cercando:

#= select * from volunteers order by lower(coalesce(first_name, email));
 first_name | last_name |       email
------------+-----------+--------------------
 Alex       | Diego     | [email protected]
 ∅          | ∅         | [email protected]
 Josh       | Broger    | [email protected]
 Josh       | Broger    | [email protected]
 Josh       | Kenton    | [email protected]

O per la tua versione completa usando ActiveRecord :

Volunteer
  .joins(:volunteer_lists)
  .where(
    "(volunteer_lists.organizer_id = ? AND organizer_type = 'Organization') OR (volunteer_lists.organizer_id IN (?) AND organizer_type = 'Collaborative')",
    organization.id, collaboratives
  )
  .order('LOWER(COALESCE("volunteers"."first_name", "volunteers"."last_name", "volunteers"."email"))')