SQL QUERY:如何在表中将随机不同的列值分配给另一个表中的不同行?

问题描述 投票:0回答:2

我正在开发一个基于一些数据库程序的桌面应用程序,就像Risiko!的游戏一样。

我需要为每个玩家分配一组行,这些行彼此不等于分配给其他玩家。

我尝试过类似的东西,但不起作用:

 `create or replace PROCEDURE  "giveterritory"
    (idpartita NUMBER,nr_partecipanti number )
   is

 begin

 DECLARE

 CURSOR cur_file IS

SELECT *
FROM Player
WHERE idgame = Player.idgame ;

var_cur cur_file%ROWTYPE;

cont number ;
nr_territories_gioc_prec number ;
G1_Terr int ;  
G2_Terr int ;  
G3_Terr int ;
G1_ID number;
G2_ID number;
G3_ID number;
begin

cont:=0 ;

for var_cur in cur_file 

loop

cont := cont + 1 ;  

    update territory
    set    Player_owner = var_cur.id_Player
    where ROWNUM = MOD( MOD ( number_RANDOM(),42 ) ,ROWNUM );
 G1_Terr := var_cur.number_territories_tot ;   -- mi salvo i territories del primo Player
 G1_ID := var_cur.id_Player ;
 end if ;
   if (cont=2 ) then 


    update territory
    set    Player_owner = var_cur.id_Player
    where ROWNUM = MOD( MOD ( number_RANDOM(),42 -G1_Terr ) , ROWNUM ) and id_territory NOT IN ( select Player_owner from territory where ;

    G2_Terr := var_cur.number_territories_tot  ;    
    end if ;
 if (cont=3 ) then 


    update territory
    set    Player_owner = var_cur.id_Player
    where ROWNUM <= 42 - G1_Terr - G2_Terr;
    --where ROWNUM <= 42 - var_cur.number_territories_tot * 2 ;
 G3_Terr := var_cur.number_territories_tot  ;   
 end if ;
 end loop;
 end;

end;`

number_random代码:

        create or replace FUNCTION  "NUMBER_RANDOM"
      return NUMBER
      is
      numbrndm int;
      begin

         select dbms_random.value(1,99999999) into numbrndm
        from dual;
   return numbrndm;
   end;
sql oracle stored-procedures plsql
2个回答
0
投票

如果我理解正确,你是否试图为每个玩家分配一组随机区域?

如果是这样,请按随机顺序对区域进行排序,并将其分配给循环播放器。这是一个应该这样做的MERGE声明。我为任何轻微的语法错误道歉:我现在不在Oracle数据库前面。

MERGE INTO territory t
USING (
WITH players AS ( SELECT rownum player#, id_player
                  FROM   player
                  WHERE  idgame=:idgame ),
players_count AS ( SELECT count(*) players_count FROM players )
-- Get the id_player for each assignment
SELECT assignedt.id_territory, p.id_player
FROM
(
  -- Assign the randomly-ordered territories to players in round-robin format
  SELECT randt.id_territory, 
     mod(rownum, pc.players_count)+1 player#
  FROM (
    -- Query the territories in a random order
    SELECT t.id_territory
    FROM   territory t
    ORDER BY dbms_random.random ) randt, players_count pc
  -- Optional:
  -- ... add a where clause to limit rownum <= some number to make 
  -- ... sure each player receives an even number of territories. 
  -- ... You'd need the count of territories to do that.
  ) assignedt inner join players p on p.player# = assignedt.player#
) u
ON ( u.id_territory = t.id_territory )
WHEN MATCHED THEN UPDATE SET t.id_player = u.id_player;

0
投票

我会在SQL选择中为每一行添加一个随机数列。然后,您可以直接在SQL中通过随机数订购记录集。

为玩家和地区列表执行此操作。

此示例适用于任何数量的地区和玩家。如果这些地区没有平分,那么玩家将获得一个额外的领土。

我们将以随机顺序遍历地区列表一次。我们将逐步完成播放器列表,直到结束,然后再次重新加载播放器列表。这根据需要多次发生。

可能需要修复此语法或逻辑。我没有Oracle实例来测试它。

CREATE OR REPLACE PROCEDURE giveterritory (pID_GAME PLS_INTEGER) IS
    CURSOR c_player IS
        SELECT id_player, dbms_random.value() rnd
        FROM players
        WHERE id_game = pID_GAME
        ORDER BY 2 desc;
    --
    CURSOR c_territory IS
        SELECT id_territory, dbms_random.value() rnd
        FROM territories
        WHERE id_game = pID_GAME
        FOR UPDATE of id_player
        ORDER BY 2 desc;
    --
    l_player_row  c_player%ROWTYPE;
    l_territory_row  c_territory%ROWTYPE;
BEGIN
    OPEN c_player;
    FETCH c_player into l_player_row;
    --
    FOR r in c_territory
    LOOP
        UPDATE territories
        SET id_player = l_player_row.id_player
        WHERE CURRENT OF c_territory;
        --
        FETCH c_player INTO l_player_row;
        IF c_player%NOTFOUND THEN
            CLOSE c_player;
            OPEN c_player;
            FETCH c_player INTO l_player_row;
        END IF;
    END LOOP;
END;
© www.soinside.com 2019 - 2024. All rights reserved.