Прямо сейчас, я действительно понятия не имею, как я мог решить это.
У меня есть пользователи, которые могут заниматься различными типами задач.
Эти задачи имеют много свойств. Я выбрал всего 4 собственность для простота.
Если я назначаю задачу пользователю, я должен дать оценку этому назначению. Эта ставка будет определять, сколько я должен заплатить за него, когда он завершит свою задачу.
У меня есть следующая таблица. Эти поля идентификатора обнуляемым (кроме user_id), и все они внешние ключи.
|-#-|-user_id-|-type_id-|-task_id-|-source_id-|-target_id-|--rate--|
| 1 | 12 | NULL | 1 | 1 | 2 | 0.0022 |
| 2 | 12 | NULL | 2 | 1 | 2 | 0.0101 |
| 3 | 12 | NULL | 1 | 2 | 1 | 0.0200 |
| 4 | 12 | NULL | 2 | 2 | 1 | 0.1011 |
| 5 | 12 | 1 | NULL | NULL | NULL | 0.0750 |
| 6 | 12 | 2 | 1 | NULL | NULL | 0.0520 |
| 7 | 12 | NULL | 1 | NULL | NULL | 0.9100 |
Конечно, существуют тарифы и для других пользователей.
Там теперь веса, просто слева направо (из столбца type_id).
Но: это важно что: Слева из первого совпадения столбца, должны быть все равен назначенным значениям задачи или NULL ценности. Направо должен быть равен назначенным значениям задачи или NULL
user_id: 12
type_id: 3
task_id: 2
source_id: 1
target_id: 2
№ 2 — 0,0101 Скорость должна быть выбрана.
user_id: 12
type_id: 1
task_id: 2
source_id: 3
target_id: 4
№ 5 — 0,0750 Скорость должна быть выбрана.
user_id: 12
type_id: 2
task_id: 1
source_id: 2
target_id: 3
№ 6 — 0,0520 Скорость должна быть выбрана.
Пока что я в порядке с этим. Но я не могу решить следующее:
user_id: 12
type_id: 2
task_id: 2
source_id: 2
target_id: 3
НИКТО должен быть выбран.
user_id: 12
type_id: 3
task_id: 1
source_id: 2
target_id: 3
НИКТО должен быть выбран.
Я думаю ты хочешь order by
а также fetch first row
:
select t.*
from t
where user_id = 12 and
(type_id = 3 or type_id is null) and
(task_id = 2 or task_id is null) and
(source_id = 1 or source_id is null) and
(target_id = 2 or target_id is null)
order by ( (type_id is not null)::int +
(task_id is not null)::int +
(source_id is not null)::int +
(target_id is not null)::int
) desc
fetch first 1 row only;
Это возвращает строку, которая соответствует вашим условиям, но с наименьшим NULL
значения (то есть самая конкретная строка).
РЕДАКТИРОВАТЬ:
Если вам нужно сопоставить их по порядку, то where
пункт выглядит так:
order by (type_id is not null)::int desc,
(task_id is not null)::int desc,
(source_id is not null)::int desc,
(target_id is not null)::int desc
Других решений пока нет …