Вот моя проблема. Предположим, у меня есть таблица под названием persons
, содержащая, помимо прочего, поля для имени человека и национального идентификационного номера, причем последний является необязательным. Для каждого фактического человека может быть несколько строк.PostgreSQL: настраиваемая логика для определения отдельных строк?
Теперь предположим, что я хочу выбрать ровно одну строку для каждого фактического человека. Для целей приложения две строки считаются относящимися к одному и тому же лицу, если: a) совпадают их идентификационные номера или b) совпадают их имена, а идентификационный номер одного или обоих - 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
.
Это довольно поздно, и я мог пропустить что-то очевидное, поэтому другие предложения о том, как достичь того, что я хочу, также будут приветствоваться. Все, что позволяет мне выбирать отдельные строки на основе более сложных критериев, чем простой список столбцов. Заранее спасибо.
Спасибо за предложение. Тем не менее, я на PostgreSQL 8.1, который, AFAIK, не имеет оконных функций. – Indrek
Не думаю, что вам нужны оконные функции: ... объединение всех выбрать уникальное имя, идентификатор из лиц , где идентификатор не является нулевым – Corey
@Corey, которая не для следующей пары '(имя, идентификатор) 'tuples *, представляющие одно и то же лицо *:' ('Bob Jones', 123) ',' ('Robert A. Jones', 123) '. – pilcrow