select a.itemId, a.name, b.itemId otherItemId, b.name othername
from item a
inner join item b on a.itemId < b.itemId
where not exists (
select * from vote v
where ((v.betterItemId = a.itemId and v.worseItemId = b.itemId)
or (v.betterItemId = b.itemId and v.worseItemId = a.itemId))
and v.userId = 1234) # << enter the userId here
order by rand()
limit 1;
- Сначала сгенерируйте все комбинации a-b, но используйте
a.id<b.id
для предотвращения дублирования (например, 1-2 и 2-1).
- Далее для каждой комбинации a-b проверьте, что (в любой перестановке лучше - хуже или хуже - лучше) элемент еще не был выбран userId (пример
1234
в запросе)
- упорядочить все результаты случайным образом, используя
order by rand()
- используйте
limit 1
, чтобы получить только 1 строку
- В выбранном, показать идентификатор и имя для обоих элементов
Чтобы отобразить его в виде двух отдельных строк, для этого следует использовать передний конец. Но чтобы сделать это чисто в MySQL, требуется хитрость. Ниже на момент написания статьи не тестировалось.
select ItemId, name
from
(
select a.itemId, a.name, @b := b.itemId
from item a
inner join item b on a.itemId < b.itemId
where not exists (
select * from vote v
where ((v.betterItemId = a.itemId and v.worseItemId = b.itemId)
or (v.betterItemId = b.itemId and v.worseItemId = a.itemId))
and v.userId = 1234) # << enter the userId here
order by rand()
limit 1
) c
union all
select itemId, name
from item d on d.itemId = @b