1

我必须根据来自 2 个不同表的多条记录向表中插入一些记录。

表: 目标player_list_items 源1:源list_items 2map_details

玩家应该播放包含项目列表的列表;需要在地图上播放列表。

该地图包含具有特定 X 和 Y 位置的占位符,我需要将 list_items 放在这些占位符后面。为此,我创建了包含随机放置在占位符后面的 list_items 的目标表。

下面是我能够将用户的 list_items 转储到目标表中的查询,但是现在的问题是如何从 source2 表中为每个 list_items 随机获取 X 和 Y 位置。

INSERT INTO player_list_items 
(player_list_list_id, player_list_player_id, player_list_item_id, player_list_item_cellX, player_list_item_cellY)

SELECT li.list_item_list_id, 584488596, li.list_item_item_id, 2, 5
FROM list_items li
WHERE li.list_item_list_id = 2

aninsert with multiple selectseven another query {update}after 这对我有用,因为这只会为每个列表的用户运行一次。

每个列表包含多个项目,因此上述查询返回多个项目并且工作正常,需要考虑的是 map_details 表还包含多个占位符,它们肯定会超过 list_items 的数量。

所需的查询应该从 map_details 表中获取所有位置 X 和 Y,然后随机分配给每个单独的项目,每个项目的位置必须是唯一的。

我已经看到了插入多个选择的示例,但它们用于单行插入,我的问题是来自多个表的多行并且也是随机的。

I have a Stored Procedure for this case因为它还有很多其他工作正常的东西,所以,如果这里有人想使用 SP 给出答案,那将是有用的,而不是我使用的问题。

希望以上内容有意义并澄清我的观点。

在此处输入图像描述

更新

我的第二个查询:

插入到 player_list_items(player_list_list_id、player_list_player_id、player_list_item_id、player_list_item_cellX、player_list_item_cellY)

SELECT list_item_list_id, 584488596, list_item_item_id,  game_map_details.cellX, game_map_details.cellY
FROM list_items
JOIN (SELECT * FROM game_map_details WHERE map_id = 1 ORDER BY RAND()) AS game_map_details
WHERE list_item_list_id = 2
GROUP BY list_item_item_id

这确实添加了 map_details 表中的数据,但数据不是随机的,实际上它只为 list_items 表中的所有 4 条记录插入了一对记录

在此处输入图像描述

问候

4

2 回答 2

0

好的,我得到了答案

使用 map_details 的光标并循环通过它来更新项目列表,这是代码以防万一它帮助某人或某人给我一个更好的主意。

UPDATE player_list_items SET player_list_item_cellX = cell_X, player_list_item_cellY = cell_Y
             WHERE player_list_id IN (
                 SELECT player_list_id FROM (
                 SELECT player_list_id FROM player_list_items 
                 WHERE player_list_player_id = playerID AND player_list_list_id = @listID AND player_list_item_cellX IS NULL
                 ORDER BY player_list_id LIMIT 1
                 ) tmp
             );
于 2012-07-06T07:57:01.280 回答
0

我不确定我是否在关注,但听起来您需要list_items加入map_details. 如果两个表都有某种序列字段,它总是从一个开始并单调增加,没有间隙,你可以加入它们。鉴于此数据:

Seq  Name
1    Barrel
2    Box
3    Crate

Seq  Position
1    13, 4
2    99, 2
3    8, 11

然后,SELECT I.Name AS ItemName, M.Position FROM Items AS I INNER JOIN Map AS M ON I.Seq = M.Seq会给你这个:

ItemName Position
Barrel   13, 4
Box      99, 2
Crate    8, 11

尽管您可能有这样一个字段,但由于您需要随机化,因此您需要在子查询中为两个表中的至少一个创建一个新序列;这里的一个线程讨论了如何在 MySQL 中这样做。在该线程中,行按特定顺序编号,但您可以按 GUID 或其他一些随机元素排序,以随机顺序获取项目。在 MS SQL 中,我会使用ROW_NUMBER(),而 Oracle 有ROWNUM,但看起来 MySQL 可能不太方便。如果您找到更好的方法,请将其添加到其他问题中,以造福后代。

您需要将您的序列号乘以地图位置与项目数量的比率,以便项目编号跨越地图编号的整个范围。请务必将此比率计算为 a FLOAT,但要将结果数字转换为 ,INT以便它们正确连接。例如,如果有 4 个项目和 10 个地图位置,您将随机排列项目并为其分配数字 1、2、3 和 4;将这些乘以 2.5(地图位置与项目的比率),然后将它们四舍五入为整数,得到 2(1 x 2.5,向下舍入为 2)、5、7 和 10。这并不完美,因为这意味着某些地图位置会比其他位置更频繁地出现。如果你随机化地图位置“和”项目的顺序,它应该是均匀的。


这是如何工作的说明。假设您正在使用这些项目:

ItemID Name
42     Barrel
79     Box
101    Crate

...并且您正在使用这些地图位置:

MapID Location
22    13, 4
38    99, 2
44    8, 11
45    7, 10

首先为这些列表中的每一个分配序列号,如其他线程中所述:

ItemID Name    Seq
42     Barrel  1
79     Box     2
101    Crate   3

MapID Location Seq
22    13, 4    1
38    99, 2    2
44    8, 11    3
45    7, 10    4
50    1, 12    5

您现在可以在 Items.Seq = Map.Seq 上将 Items 加入 Map:

ItemID Name    Seq Location
42     Barrel  1   13, 4
79     Box     2   99, 2
101    Crate   3   8, 11

但是,您总是将您的项目分配给地图中的第一个元素。要解决此问题,您可以随机化地图元素的顺序,或者将项目的序列号乘以两个计数的比率 (5/3):

ItemID Name    Seq  NewSeq
42     Barrel  1    1 * 1.6667 = 1.6667 = 1
79     Box     2    2 * 1.6667 = 3.3333 = 3
101    Crate   3    3 * 1.6667 = 5.0000 = 5

...现在,项目在地图位置之间均匀分布,分别位于 1、3 和 5,而不是在地图的开始处聚集。请注意,只要项目列表和地图列表未更改,项目每次仍将具有相同的位置,因此您最好为地图位置分配随机序列号。

于 2012-07-02T17:33:13.850 回答