[英]insert into table with multiple records from multiple tables
我必須根據來自2個不同表的多個記錄將一些記錄插入表中。
表: 目標 : player_list_items
源1: list_items
源2: map_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 selects
的insert with multiple selects
還是even another query {update}
都將對我有用,因為每個列表的用戶只能運行一次。
每個列表包含多個項目,因此上面的查詢返回了多個項目,並且工作正常,需要考慮的是map_details表還包含多個占位符,並且它們肯定大於list_items的數量。
必需的查詢應該從map_details表中獲取所有位置X和Y,然后將其隨機分配給每個單獨的項目,每個項目的位置必須唯一。
我已經看到了多個用於插入的選擇的示例,但是它們是用於單行插入的,我的問題是來自多個表的多個行也是隨機的。
I have a Stored Procedure for this case
因為它還有很多其他的東西都可以正常工作,因此,如果這里有人想要使用SP給出答案,那將是有用的,並且對我來說不是問題。
希望以上內容有意義並闡明我的觀點。
更新
我的第二個查詢:
插入INTO播放器_列表_項目(播放器_列表_列表ID,播放器_列表_播放器ID,播放器_列表_項目_ID,播放器_列表_項目_cellX,播放器_列表_項目_單元Y)
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條記錄,它僅插入一對記錄
問候
我不確定我是否在關注,但聽起來您需要將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可能不太方便。 如果您找到更好的方法,請將其添加到另一個問題中,以造福子孫后代。
您需要將序列號乘以地圖位置與項目數量的比率,以使項目編號跨越地圖編號的整個范圍。 確保將此比率計算為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連接到Items.Seq = Map.Seq上的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的地圖位置之間平均分配,而不是在地圖開始時集中。 請注意,只要項目列表和地圖列表保持不變,項目每次仍將具有相同的位置,因此最好將隨機序列號分配給地圖位置。
好吧,我得到了答案
使用了光標作為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
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.