2014-11-06 120 views
0

我正在處理一個我從來沒有做過的查詢,並且我一直在堅持如何繼續。我想成爲一個插入命令。使用子查詢插入到表中

我想要做的僞代碼是這樣的:

For each player 
    insert into CurrentHand table by getting x number of cards needed 
     so all the players have 10 cards in their hands. 

所以,如果玩家1將獲得7張新卡,如果他有在自己手中3張牌。如果他手上有5張牌,Play 2將獲得5張新牌。

到目前爲止,我已經看到了這個select語句,但感覺就像我使用了錯誤的方法。

DECLARE @MaxHandCount int 
SET @MaxHandCount = 10 

SELECT Player.PlayerId 
    , (SELECT COUNT(1) FROM CurrentHand WHERE PlayerId = Player.PlayerId AND IsUsed = 0) AS CurrentHandCount 
    , (@MaxHandCount - (SELECT COUNT(1) FROM CurrentHand WHERE PlayerId = Player.PlayerId AND IsUsed = 0)) AS NeededHandCount 
    , CardId 
FROM Player, AvailableCard 
WHERE Cardid IN (SELECT CardId FROM CurrentHand WHERE IsUsed = 0) 
ORDER BY PlayerId 

表結構如下:

Player 
    - PlayerId 

AvailableCard 
    - CardId 
    - CardValue 

CurrentHand 
    - PlayerId 
    - CardId 
    - IsUsed 

非常感謝。

+0

「IsUsed」標誌的用途是什麼?你使用什麼版本的SQL Server?請正確標記問題。 – TomT 2014-11-06 22:07:22

+0

服務器爲MS Sql Server 2012. IsUsed的用途是跟蹤哪些卡已經播放過,以便以前播放的卡不會再次被選中。 – 2014-11-06 22:17:05

回答

1

這非常有趣。這是我「解決」所需牌的解決方案。請閱讀代碼中的表揚。這只是選擇,但我相信你可以找出你自己的插入。檢查出fiddle

-- for each card in player's hand assign a sequence number 
with cte_currenthand as 
(
    select PlayerId, 
    rank() over(partition by PlayerId order by CardId) CardSeq 
    from CurrentHand 
    where IsUsed = 0 
) 
-- for each player generate a sequence 1..10 
, cte_maxhand as 
(
select p.PlayerId, x.seq 
from Player p 
cross join (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) x(seq) 
) 
-- get cards the players need and assign them new sequence numbers 
-- basically cte_maxhand minus cte_currenthand 
, cte_needed as 
(
    select mh.PlayerId, row_number() over(order by mh.seq) seq 
    from cte_maxhand mh 
    left join cte_currenthand ch 
    on ch.CardSeq = mh.seq 
    and ch.PlayerId = mh.PlayerId 
    where ch.CardSeq is null 
) 
-- generate a random sequence on remaining cards 
, cte_deal as 
(
    select CardId, row_number() over(order by CHECKSUM(NewId())) seq 
    from AvailableCard ac 
    where not exists (
    select * 
    from CurrentHand ch 
    where ch.CardId = ac.CardId 
    ) 
) 
-- deal the cards 
select n.PlayerId, d.CardId 
from cte_needed n 
inner join cte_deal d on d.seq = n.seq 
+0

完美運作。事實證明這比我想象的要複雜得多。然後再簡單的事情通常以這種方式結束。 – 2014-11-07 04:49:58

+0

@KathyJudd我很高興能幫上忙。但我仍然認爲你應該更好地在你的應用層而不是數據庫中實現它。乾杯 – TomT 2014-11-07 08:45:33

0

樣本表結構:

CREATE TABLE [dbo].[cards](
    [player] [nvarchar](20) NOT NULL, 
    [number] [int] NOT NULL 
    ) 

樣本數據:

insert into cards values ('p1',3) 
insert into cards values ('p2',5) 
insert into cards values ('p3',4) 
insert into cards values ('p4',2) 

插入:

insert into cards 
select player,10-sum(number) as number 
from cards 
group by player 
0

DECLARE @MaxHandCount int 
 
SET @MaxHandCount = 10 
 

 
SELECT Player.PlayerId 
 
    , Count(CardID) AS CurrentHandCount 
 
    , @MaxHandCount - Count(CardID) AS NeededHandCount 
 
    , CardId 
 
FROM Player 
 
join CurrentHead on Player.PlayerID = CurrentHead.PlayerID 
 
WHERE IsUsed = 0 
 
Group by Player.PlayerID 
 
ORDER BY PlayerId