【问题标题】:insert into table with multiple records from multiple tables插入包含来自多个表的多条记录的表
【发布时间】:2012-07-03 02:58:35
【问题描述】:

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

表: 目标player_list_items 来源1list_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

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

每个列表包含多个项目,因此上述查询返回多个项目并且工作正常,需要考虑的是 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 条记录插入了一对记录

问候

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    好的,我知道了

    将光标用于 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
                 );
    

    【讨论】:

      【解决方案2】:

      我不确定我是否在关注,但听起来您需要加入 list_itemsmap_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
      

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

      您需要将序列号乘以地图位置与项目数量的比率,以便项目编号涵盖整个地图编号范围。请务必将此比率计算为FLOAT,但要将结果数字转换为INT,以便它们正确连接。例如,如果有四个项目和十个地图位置,您将随机排列这些项目并为其分配数字 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 处,而不是在地图的开始处聚集。请注意,只要项目列表和地图列表保持不变,项目每次仍具有相同的位置,因此您最好为地图位置分配随机序列号。

      【讨论】:

      • @JOAT 感谢您的回复,恐怕您没有得到实际场景或者我没有解释......让我编辑我的问题以添加一些示例
      • 我不明白什么?再次阅读您的帖子,您似乎很清楚您需要什么:您有一个对象列表,并且您希望将每个对象与另一个列表中的记录随机关联,没有一对多的关系。为此,您可以将序列号分配给大集合,将相同范围内的随机数分配给小集合。我会在我的回答中举一个更具体的例子。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-17
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多