Вот моя проблема.Предположим, у меня есть таблица с именем persons
, содержащая, помимо прочего, поля для имени человека и его национального идентификационного номера, причем последнее является необязательным.Для каждого человека может быть несколько строк.
Теперь предположим, что я хочу выбрать ровно одну строку для каждого человека.В целях приложения считается, что две строки относятся к одному и тому же лицу, если а) их идентификационные номера совпадают или б) их имена совпадают, а идентификационный номер одного или обоих равен NULL.SELECT DISTINCT здесь не годится: я не могу сделать DISTINCT ON (name, id)
, потому что тогда две строки с одним и тем же именем, где идентификатор одного равен NULL, не будут совпадать (что неверно, их следует считать одинаковыми).Я не могу сделать DISTINCT ON (name)
, потому что тогда строки с одинаковыми именами, но разными идентификаторами будут совпадать (опять же, неверно, их следует считать разными).И я не могу сделать DISTINCT ON (id)
, потому что тогда все строки, где ID равен NULL, будут считаться одинаковыми (очевидно, некорректными).
Есть ли способ переопределить способ, которым PostgreSQL сравнивает строки, чтобы определить, действительно ли ониидентичны?Я предполагаю, что поведение по умолчанию для DISTINCT ON (name, id)
будет примерно таким же, как IF a.name = b.name AND a.id = b.id THEN IDENTICAL ELSE DISTINCT
.Я хотел бы переопределить его к чему-то вроде IF a.id = b.id OR (a.name = b.name AND (a.id IS NULL OR b.id IS NULL)) THEN IDENTICAL ELSE DISTINCT
.
Уже довольно поздно, и я, возможно, пропустил что-то очевидное, поэтому другие предложения о том, как добиться того, чего я хочу, также будут приветствоваться.Все, что позволило мне выбрать отдельные строки на основе более сложных критериев, чем простой список столбцов.Заранее спасибо.