Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server Sql-循环两个表并根据条件求和一个值_Sql Server - Fatal编程技术网

Sql server Sql-循环两个表并根据条件求和一个值

Sql server Sql-循环两个表并根据条件求和一个值,sql-server,Sql Server,我正在为一个基于点的投注程序开发一个项目,如果需要,可以在sql server上创建一个存储过程,该存储过程执行以下操作: 如果用户在团队中下注并获得正确结果,则加3分; 如果结果与用户猜测的结果不同,但仍然能够正确判断团队是赢是输还是平,则加1分 i、 e.用户下注皇家马德里-巴塞罗那;用户猜测2-1;结果1-0; 如果用户出错,他不会得到任何分数。 我一直在寻找这样做的方法,但我想不出一个方法。 这很可能是一个不切实际的问题,因为我们都必须从某个地方开始。 我考虑过循环,这在理论上是我需要做

我正在为一个基于点的投注程序开发一个项目,如果需要,可以在sql server上创建一个存储过程,该存储过程执行以下操作:

如果用户在团队中下注并获得正确结果,则加3分; 如果结果与用户猜测的结果不同,但仍然能够正确判断团队是赢是输还是平,则加1分 i、 e.用户下注皇家马德里-巴塞罗那;用户猜测2-1;结果1-0; 如果用户出错,他不会得到任何分数。 我一直在寻找这样做的方法,但我想不出一个方法。 这很可能是一个不切实际的问题,因为我们都必须从某个地方开始。 我考虑过循环,这在理论上是我需要做的,但我需要遍历bets表中的每一行,并将其值与games表中每一行的值进行比较

如果你能帮助我,那就太好了。谢谢

编辑:噢,糟了。对不起,我正要添加表,但我忘了。好的,给你:

-投注表:

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);
-游戏桌:

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);
-我尝试过这种方法和其他方法,但没有成功:

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:我的解决方案可能不是最有效的,但仍然:

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 nickname=@nickname)
    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 num_bet=@cont)
        begin
            set @id_game=(select id_game from Bets where num_bet=@cont)
            set @goals_home_bet=(select goals_home from Bets where num_bet=@cont)
            set @goals_visitor_bet=(select goals_visitor from Bets where num_bet=@cont)
            set @cont1=1
            while(@cont1<(select max(id_game) from Games))
            begin
                if(@id_game=(select id_game from Games where id_game =@cont1))
                begin
                    set @goals_home_game=(select goals_home from Games where num_game=@cont1)
                    set @goals_visitor_game=(select goals_visitor from Games where num_game=@cont1)

                    if(@goals_home_bet=@golos_casa_jogo and @golos_fora_aposta=@golos_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 (@goals_home_bet=@goals_visitor_bet and @goals_home_game=@goals_visitor_bet))
                        set @points+=1
                end

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

END
为您的目标从bit切换到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 spGetUsersTotalPoints
as
begin
    select id_user, TotalPoints
    from vUserTotalPoints
end

同样,如果您在批处理方面遇到错误,只需一次运行一条语句,而不是依赖go关键字。一些SQL前端不喜欢这样。

显示您的表架构以及您迄今为止在查询方面所做的尝试。样本数据和结果总是一个加号。这里是一个很好的起点。对不起,忘记添加信息了。更新!你为什么用比特来实现目标?嗨,谢谢。我没用钻头。这只是第一次犯的一个错误:。我在while循环中使用while循环成功地获得了我想要的结果。可能不是最有效的方法。我只是想了解你在那里做了什么。我是sql新手,我对sql还不太熟悉。我知道lol。我会将我的解决方案粘贴到主帖子上,让你看看我做了什么。此解决方案将工作分解为两到三个主要查询,并将这些查询封装到视图中,以便于重用。第一个视图根据游戏id将来自游戏的数据与来自下注的数据进行匹配,然后使用一些内联逻辑确定案例语句中该下注的分数。第二个视图使用该数据并按用户id对其进行分组,以便它可以获得每个用户下注范围内的点数总和。第三个查询只是一个示例select语句,它显示了如果您想按用户筛选数据或从过程中运行数据,可以如何使用这些数据。不使用循环的好处是,此解决方案中只运行3个select语句,而不是上下文表的每行运行一个select语句。编辑:我刚看过你的解决方案。为了得到所需的结果,需要运行大量查询。也许你正在处理一个小数据集,你更愿意坚持你所知道的,因为你是维护它的人,但至少值得看一下我的示例解决方案中的一些关键部分,以便让你进一步了解。一旦你习惯了SQL,它就会非常高效。是的,它有很多问题。我担心如果两个表中都有太多RWO,它最终会运行得更慢。老实说,我甚至不知道SQL数据库的速度有多快。另外,我尝试了您的答案,但它给了我一个错误:CREATEVIEW必须是批处理中的唯一语句。我希望将其保存在存储过程中,以便在需要时从UI调用它。不确定如何运行它,但go关键字确保视图创建语句是每个批处理中唯一的语句。如果这对您不起作用,只需一次运行三条语句中的每一条。如果还不清楚,就问吧。我将用一个使用这些视图的示例存储过程更新我的答案,您可以使用这些视图。
create procedure spGetUsersTotalPoints
as
begin
    select id_user, TotalPoints
    from vUserTotalPoints
end