0

我正在尝试做一些我认为相当棘手并且无法绕开它的事情。有点让我发疯。似乎它应该比它更容易。

所以我有两张桌子。我随机显示两个项目。当您选择一个项目时,它会作为对该项目的投票进入数据库,其中item ID存储在win_id列中,另一个项目进入该lst_id列。然后它显示另外两个随机项目,依此类推。现在我的问题是,一旦他们选择了一个项目,我就不希望这两对再次显示给该用户。但是,这些项目可以与其他未投票反对的项目一起显示。希望这是从那时起。这是我尝试失败的查询。

SELECT * FROM (SELECT be.media_id FROM battle_entries as be 
WHERE be.btype=1 AND be.mature=1 AND be.mem_id!=1 
AND NOT EXISTS (SELECT * FROM battle_votes as bv 
WHERE bv.win_id = be.media_id AND bv.mem_id=1 AND bv.lst_id=be.media_id)) s ORDER BY RANDOM() LIMIT 2";

win_idlst_id用户选择的对。我永远不希望这两个再次一起显示给同一个用户,如果他们存在于该用户的battle_votes 表中,但仍然与其他未一起显示的项目一起随机选择。

这是表格

战斗条目

----------------------------------------------------
| btl_id | mem_id | posted | media_id | active |
----------------------------------------------------

战斗投票

----------------------------------------------------
| btl_id | mem_id | win_id | lst_id | posted |
----------------------------------------------------

如果有更好的方法来使用不同的模式,如果这是不可能的,我也愿意接受。

编辑: 最好我可以再次解释一下。

我的查询选择了用户未投票的 2 个随机项目。一旦用户选择了一个,就会在battle_votes 表中创建一个新行。选择item ID的进入win_id列,未选择的进入lst_id列。This is a single row.现在下次它进行随机选择以显示另外两个项目时,我不希望这两个项目再次显示为 a pair,但每个项目都可以显示为另一个尚未进入 Battle_votes 表的项目作为 a pair。我知道这可能会令人困惑。

基本上我不希望同一对再次一起出现,如果他们选择了任何一个项目。

4

2 回答 2

1

我认为最简单的方法是将行转为列,选择您需要的一对,然后将其转回:

with cte1 as (
    select
        be.media_id
    from battle_entries as be
    where be.btype = 1 and be.mature = 1 and be.mem_id != 1 
), cte2 as (
    select
        be1.media_id as media_id1,
        be2.media_id as media_id2
    from cte1 as be1
        inner join cte1 as be2 on be2.media_id <> be1.media_id
), cte3 as (
    select c.media_id1, c.media_id2
    from cte2 as c
    where
        not exists
        (
            select *
            from battle_votes as bv 
            where
                bv.mem_id = 1 and
                (
                    bv.win_id = c.media_id1 and bv.lst_id = c.media_id2 or
                    bv.win_id = c.media_id2 and bv.lst_id = c.media_id1
                )
        )
    order by random()
    limit 1
)
select media_id1 as media_id from cte3
union all
select media_id2 as media_id from cte3

sql fiddle demo

于 2013-08-18T05:45:45.307 回答
0

您要么需要单独的战斗和胜利表格,要么只需要战斗表格中的额外列。添加两个 ID,但确保较小的 ID 始终是第一个。

(btl_id, mem_id, id1, id2, win_id, lst_id, ...)

然后你只需在(mem_id,id1,id2). 如果您没有使用特别垃圾的 ORM,那么您也可以放弃btl_id- 这是多余的。

于 2013-08-18T07:17:37.660 回答