2017-06-15 25 views
3

我工作的一個項目(基於點)投注程序的值,如果需要SQL Server上創建一個存儲過程,執行以下操作:的Sql - 遍歷兩個表,總結根據病情

  • 如果用戶在團隊中投注並獲得正確結果,則總計3分;
  • 總和1分,如果結果與用戶猜測的結果不同,但仍設法正確判斷球隊是否贏,輸或關聯 (即用戶對皇馬 - 巴塞羅那投注;用戶猜測2 - 1;結果1 - 0);
  • 如果用戶得到任何錯誤,他不會得到任何分數。

我一直在尋找一種方式來做到這一點,但我無法找出一種方法。 這可能是一個不好的問題,我們都必須從某個地方開始。 我想過循環,這在理論上是我需要做的,但我需要遍歷賭注表中的每一行,並將其值與遊戲表中每行的值進行比較。

如果你能幫助我,那會很棒。謝謝。

編輯:哦,拍攝。對不起,我正要添加表格,而我忘記了。那麼,在這裏,他們是:

-Bets表:

CREATE TABLE Bets(
    id_bet  NUMERIC(18,0) NOT NULL PRIMARY KEY 
    ,id_user  NUMERIC(18,0) 
    ,id_game  NUMERIC(18,0) 
    ,date   NUMERIC(8,0) 
    ,time   NUMERIC(4,0) 
    ,goals_home NUMERIC(18,0) 
    ,goals_visitor NUMERIC(18,0) 
); 
INSERT INTO Bets(id_bet,id_user,id_game,date,time,goals_home,goals_visitor) VALUES (1,1,4,20170614,1600,1,1); 
INSERT INTO Bets(id_bet,id_user,id_game,date,time,goals_home,goals_visitor) VALUES (2,1,3,20170614,1600,1,1); 
INSERT INTO Bets(id_bet,id_user,id_game,date,time,goals_home,goals_visitor) VALUES (3,7,3,20170614,1600,1,1); 
INSERT INTO Bets(id_bet,id_user,id_game,date,time,goals_home,goals_visitor) VALUES (4,7,4,20170614,1600,1,1); 

-games表:

CREATE TABLE Games(
    id_game   NUMERIC(18,0) NOT NULL PRIMARY KEY 
    ,num_game  NUMERIC(18,0) 
    ,id_club_home NUMERIC(18,0) 
    ,id_club_visitor NUMERIC(18,0) 
    ,id_competition NUMERIC(18,0) 
    ,goals_home  NUMERIC(18,0) 
    ,goals_visitor NUMERIC(18,0) 
    ,date   NUMERIC(8,0) 
    ,time   NUMERIC(4,0) 
); 
INSERT INTO Games(id_game,num_game,id_club_home,id_club_visitor,id_competition,goals_home,goals_visitor,date,time) VALUES (1,1,3,6,2,2,2,20170614,1700); 
INSERT INTO Games(id_game,num_game,id_club_home,id_club_visitor,id_competition,goals_home,goals_visitor,date,time) VALUES (3,2,4,3,2,1,3,20170614,1800); 
INSERT INTO Games(id_game,num_game,id_club_home,id_club_visitor,id_competition,goals_home,goals_visitor,date,time) VALUES (4,3,3,4,2,1,3,20170614,1800); 
INSERT INTO Games(id_game,num_game,id_club_home,id_club_visitor,id_competition,goals_home,goals_visitor,date,time) VALUES (5,4,6,3,2,2,3,20170614,1800); 
INSERT INTO Games(id_game,num_game,id_club_home,id_club_visitor,id_competition,goals_home,goals_visitor,date,time) VALUES (6,5,4,6,2,NULL,NULL,20170614,1600); 

-I've想這(和其他的方法,但沒不保存它們):

CREATE PROCEDURE [dbo].[Count_Points] @valor AS INT OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @a AS INT 
    DECLARE @goals_home_bet AS NUMERIC(18, 0) = (
      SELECT Bets.goals_home 
      FROM Bets 
      INNER JOIN Games ON Bets.id_game = Games.id_game 
      ) 
    DECLARE @goals_visitor_bet AS NUMERIC(18, 0) = (
      SELECT Bets.goals_visitor 
      FROM Bets 
      INNER JOIN Games ON Bets.id_game = Games.id_game 
      ) 
    DECLARE @goals_home_games AS NUMERIC(18, 0) = (
      SELECT Games.goals_home 
      FROM Bets 
      INNER JOIN Games ON Bets.id_game = Games.id_game 
      ) 
    DECLARE @goals_visitor_games AS NUMERIC(18, 0) = (
      SELECT Games.goals_visitor 
      FROM Bets 
      INNER JOIN Games ON Bets.id_game = Games.id_joid_gamego 
      ) 

    SET @valor = 0 
    SET @a = 1 
    SET @valor = sum(@valor + 3) 

    WHILE (
      (
       SELECT max(id_bet) 
       FROM Bets 
       ) > @a 
      ) 
    BEGIN 
     SET @a += 1 
    END 
END 

它只是用於測試它是否工作(因此僅引用值3),但顯然我只能得到3的值。其他方式我也會得到3或者甚至是。

編輯2:我的解決方案(可能不是最有效的,但仍然):從bit

CREATE PROCEDURE [dbo].[Calculate_Points] 
     @control as int output, 
     @points as int output, 
     @nickname varchar(50) 

AS 
BEGIN 

    SET NOCOUNT ON; 

    declare @cont numeric(18,0)=1 
    declare @cont1 numeric(18,0) 
    declare @id_user numeric(18,0)=(select num_user from Users where [email protected]) 
    declare @id_game numeric(18,0) 
    declare @goals_home_bet numeric(18,0) 
    declare @goals_visitor_bet numeric(18,0) 
    declare @goals_home_game numeric(18,0) 
    declare @goals_visitor_game numeric(18,0) 
    set @points=0 


    while(@cont<=(select max(num_bet) from Bets)) 
    begin 
     if exists (select id_user from Bets where @id_user=id_user and [email protected]) 
     begin 
      set @id_game=(select id_game from Bets where [email protected]) 
      set @goals_home_bet=(select goals_home from Bets where [email protected]) 
      set @goals_visitor_bet=(select goals_visitor from Bets where [email protected]) 
      set @cont1=1 
      while(@cont1<(select max(id_game) from Games)) 
      begin 
       if(@id_game=(select id_game from Games where id_game [email protected])) 
       begin 
        set @goals_home_game=(select goals_home from Games where [email protected]) 
        set @goals_visitor_game=(select goals_visitor from Games where [email protected]) 

        if(@[email protected]_casa_jogo and @[email protected]_fora_jogo) 
         set @pontos+=3 
        else if((@goals_home_bet>@goals_visitor_bet and @goals_home_game>@goals_visitor_game) or (@goals_home_bet<@goals_visitor_bet and @goals_home_game<@goals_visitor_bet) or (@[email protected]_visitor_bet and @[email protected]_visitor_bet)) 
         set @points+=1 
       end 

       set @cont1+=1 
      end 
     end 
     set @cont+=1 
    end 

END 
+0

顯示您的表格模式以及目前爲止嘗試查詢的內容。樣本數據和結果始終是一個優點。 –

+0

這裏是一個開始的好地方。 http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ –

+0

對不起,忘了添加信息。更新! – taiko

回答

1

切換到int爲自己的目標,然後嘗試這樣的事:

create view vUserPointsPerGame 
as 
select 
    id_user, bets.id_game, 
    case 
     -- you could also just compare the goal differences if you want 
     when bets.goals_home = games.goals_home and bets.goals_visitor = games.goals_visitor then 3 
     when (bets.goals_home >= bets.goals_visitor and games.goals_home >= games.goals_visitor) or (bets.goals_home < bets.goals_visitor and games.goals_home < games.goals_visitor) then 1   
     else 0 
    end as Points 
from 
    bets 
    join games on bets.id_game = games.id_game 

go 

create view vUserTotalPoints 
as 
    select id_user, sum(points) as TotalPoints 
    from vUserPointsPerGame 
    group by id_user 
go 

select * from vUserTotalPoints 

那會向用戶返回所有投注的總分。

您可以使其更高效,但這裏的主要想法是您不需要循環或存儲過程來完成您想要在此完成的任務。

編輯:你提到你想要一個過程,因爲它更容易消耗。這裏有一個,將獲得的總積分爲單個用戶:

create procedure spGetUserTotalPoints 
(
    @iUserId int, 
    @oTotalPoints int output 
) 
as 
begin 
    select @oTotalPoints = TotalPoints 
    from vUserTotalPoints 
    where id_user = @iUserId 
end 

而且這裏的另一個,將獲得的總積分爲每個用戶對所有已知用戶:

create procedure spGetUsersTotalPoints 
as 
begin 
    select id_user, TotalPoints 
    from vUserTotalPoints 
end 

同樣,如果你是獲取有關批次的錯誤,只需按照每個語句執行一次,而不是依賴關鍵字go。一些SQL前端不喜歡那樣。

+0

嗨,謝謝。我沒有使用位。這只是在convertcsv(第一次:)的錯誤)。我設法在while循環內獲得了我想要的結果。可能不是最有效的方法。 我只是想了解你在那裏做了什麼。我是新來的sql,並且我對此還不放心(令人震驚,我知道哈哈)。我會將我的解決方案粘貼在主帖上,讓你看看我做了什麼。 – taiko

+0

該解決方案將工作分解爲兩個或三個主要查詢,並將這些查詢封裝到視圖中以便於重複使用。第一個視圖根據遊戲ID匹配來自遊戲的數據和來自投注數據,然後使用一些內聯邏輯來確定該投注的得分應該是多少(案例陳述)。第二個視圖使用該數據並按用戶ID對其進行分組,以便它可以獲得範圍爲每個用戶的投注的點數總和。第三個查詢只是一個示例select語句,顯示如果您想按用戶過濾或從過程運行數據,可以如何使用這些數據。 –

+0

不使用循環的好處在於,在此解決方案中僅運行3個select語句,而不是每行上下文表中的一個。編輯:我只是看你的解決方案。這是很多查詢正在運行,以獲得您需要的結果。也許你正在處理一個小的數據集,並且你更願意堅持你所知道的,因爲你是維護它的人,但至少看看我的示例解決方案的一些關鍵部分是值得的,你進一步學習。一旦你對它感到滿意,SQL可以非常有效 –