【问题标题】:How to use user variable as counter with inner join queries that contains GROUP BY statement?如何将用户变量用作包含 GROUP BY 语句的内部联接查询的计数器?
【发布时间】:2015-04-24 19:51:48
【问题描述】:

我有 2 张桌子 oddsmatches

匹配:有 match_idmatch_date

赔率:有idtimestampresultodd_valueuser_idmatch_id

我有一个查询,从这些表中为每个用户获取以下信息:

  1. winnings : 每个用户的中奖投注。 (当odds.result = 1时)
  2. loses : 每个用户的投注失败。(当odds.result != 1 时)
  3. 积分:每个用户的积分。(odds.odd_value 的总和)每个用户。
  4. 奖金:对于每连续 5 次获胜,我想为这个变量添加额外的奖金。 (针对每个用户)

如何计算奖金? 我尝试使用此查询,但遇到了一个问题:(您可以在这里查看SQL Fiddle

计算出的红利并不适合所有用户:

第一个用户:(奖金:13,奖金=2)。

第二个用户:(奖金:8,红利=2)这里的红利应该是1。

第三个用户:(奖金:14,红利=3)这里的红利应该是2。

为什么查询没有正确计算bonus

        select  d.user_id,
        sum(case when d.result = 1 then 1 else 0 end) as winnings, 
        sum(case when d.result = 2 then 1 else 0 end) as loses,
        sum(case when d.result = 1 then d.odd_value else 0 end) as points,
        f.bonus
FROM odds d
    INNER JOIN
    (
      SELECT  
            user_id,SUM(CASE WHEN F1=5 THEN 1 ELSE 0 END) AS bonus
        FROM
        (
          SELECT 
            user_id,
            CASE WHEN result=1 and @counter<5 THEN @counter:=@counter+1 WHEN result=1 and @counter=5 THEN @counter:=1 ELSE @counter:=0 END AS F1
          FROM odds o
          cross join (SELECT @counter:=0) AS t
          INNER JOIN matches mc on mc.match_id = o.match_id
           WHERE MONTH(STR_TO_DATE(mc.match_date, '%Y-%m-%d')) = 2 AND 
                  YEAR(STR_TO_DATE(mc.match_date, '%Y-%m-%d')) =  2015 AND
                  (YEAR(o.timestamp)=2015 AND MONTH(o.timestamp) = 02)            
        ) Temp
        group by user_id
        )as f on f.user_id = d.user_id
      group by d.user_id

【问题讨论】:

  • "为每个获胜值加 0.5 到奖金" -- 您的查询中没有任何名为 bonus 的内容。示例数据和所需结果可能有助于阐明您想要做什么。
  • @Strawberry 它没有丢失!链接有效
  • @GordonLinoff 我添加了一些示例并进行了一些更改,您现在可以检查一下吗
  • 对不起,我没有得到奖金的公式,你能否更详细地解释一下如何计算使用 id=100 和用户 id=200 的奖金,这将有很大帮助跨度>
  • @Alex 对于每个 (1,1,1,1,1) 连胜我将 1 添加到奖励变量并按 user_id 分组,在此连胜之后我应该将 counter (临时变量)设为零以开始计算新的连胜。

标签: mysql aggregate-functions


【解决方案1】:

我不确定您的结果与matches 表的关系如何,

如果需要,您可以添加回 WHERE / INNER JOIN 子句。

这里是link to fiddle

last iteration 根据您的 cmets:

这是一个查询:

SET @user:=0;

select  d.user_id,
        sum(case when d.result = 1 then 1 else 0 end) as winnings, 
        sum(case when d.result = 2 then 1 else 0 end) as loses,
        sum(case when d.result = 1 then d.odd_value else 0 end) as points,
        f.bonus
FROM odds d
    INNER JOIN
    (
      SELECT  
            user_id,SUM(bonus) AS bonus
        FROM
        (
          SELECT 
            user_id,
            CASE WHEN result=1 and @counter<5 AND @user=user_id THEN @counter:=@counter+1 

                 WHEN result=1 and @counter=5 AND @user=user_id THEN @counter:=1 

                 WHEN result=1 and @user<>user_id THEN @counter:=1 
                 ELSE 
                 @counter:=0 
            END AS F1,
            @user:=user_id,
            CASE WHEN @counter=5 THEN 1 ELSE 0 END AS bonus 
          FROM odds o
          ORDER BY user_id , match_id         
        ) Temp
        group by user_id
        )as f on f.user_id = d.user_id
      group by d.user_id

【讨论】:

  • 这实际上是一个错误的答案,因为我不想在 user_id 更改时将计数器设为零。当用户更改时,您将其设为零。例如,某个用户的连续记录可能会被另一个用户的另一个记录中断。这不应该使计数器为零,它应该仍然为该用户计算相同的连胜,因为它没有面临失败的结果,它只是被另一个用户的获胜结果打断。
  • 我希望它有效:sqlfiddle.com/#!2/c2f207/2 如果连续被result=2 打断,计数器不会归零
  • 我没有发现任何问题。您只是不再使用我的建议 ORDER BY。所以这是你的顺序。 sqlfiddle.com/#!2/c2f207/3 什么结果是错误的?为什么?
  • 如果您需要其他订单,请尝试sqlfiddle.com/#!2/c2f207/5 我刚刚添加了ORDER BY user_id, match_id 对于您提供的数据,所有奖金都是=1。那是你的目标吗?
  • 我亲爱的朋友,如果您检查为user_id=300 提供的链接中的结果值,您会发现它们是这样的(1,1,1,1,2,1,1,1,1,1,1,1,1,1) 与此值bonus 应该是1(因为前 4 个 1 被 2 中断,因此计数器将为零,然后在此之后 2 计数器将再次开始计数,直到变为 5 然后 bonus 将为 1,计数器将回到零并重新开始它会一直计数到四,因此它不会在bonus 中添加另一个 1)但在链接中它给出的bonus 值等于2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多