如何用丢失的数字求和用最新记录取代

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

假设游戏有5个级别,并且每个级别的玩家可以获得1、2和3的分数。玩家X拥有以下数据:

Level | Attempt | Score
1     | 1       | 2  
1     | 2       | 3
2     | 1       | 3
3     | 1       | 3
4     | 1       | 1
4     | 2       | 3
5     | 1       | 2
5     | 2       | 2
5     | 3       | 3

现在,我想SUM尝试GROUP BY得分,但采用特殊方式:

尝试1:只需2 + 3 + 3 + 1 + 3 = 12

尝试2:现在,级别2和3没有尝试2,但是我仍然想使用他们最近的分数进行累加:3 + 3 + 3 + 3 + 2 = 14

尝试3:我想再次将所有级别与其最近的分数相加(如果没有尝试3),所以我得到3 + 3 + 3 + 3 + 3 = 15

如何使用SQL? 请注意,尝试次数没有限制,因此玩家实际上可以尝试100次等级,而我必须提供100次。

sql vertica
1个回答
0
投票

然后,可能是这样:

WITH
-- your input ...
input(level,attempt,score) AS (
          SELECT 1,1,2
UNION ALL SELECT 1,2,3
UNION ALL SELECT 2,1,3
UNION ALL SELECT 3,1,3
UNION ALL SELECT 4,1,1
UNION ALL SELECT 4,2,3
UNION ALL SELECT 5,1,2
UNION ALL SELECT 5,2,2
UNION ALL SELECT 5,3,3
)
-- your input ends here
, -- replace comma with WITH in real query ..
-- creating a table with 5 rows per each of the 3 attempts
frame (level,attempt) AS (
  SELECT
     i.level
   , a.attempt
   FROM input i
   CROSS JOIN (
     SELECT DISTINCT
       attempt
     FROM input
    ) a
   WHERE i.attempt=1
)
-- SELECT * FROM frame; -- un-comment this line to test the frame table
,
gapfilled AS (
-- Query before GROUPing: left join the frame table with the input table
-- and fill the resulting NULLs using the LAST_VALUE ( ... IGNORE NULLS) 
-- OLAP function. If you can take a previous one, pick it, if not , pick
-- a following one. 
-- Vertica has named OLAP windows, which we use here - one forward, one backward
  SELECT
    frame.level
  , NVL(
      LAST_VALUE(input.attempt IGNORE NULLS) OVER(fwd)
    , LAST_VALUE(input.attempt IGNORE NULLS) OVER(bwd)
    )  AS attempt
  , NVL(
      LAST_VALUE(input.score   IGNORE NULLS) OVER(fwd) 
    , LAST_VALUE(input.score   IGNORE NULLS) OVER(bwd)
    )  AS score
  FROM frame LEFT JOIN input USING(level,attempt)
  WINDOW fwd AS (PARTITION BY frame.attempt ORDER BY frame.level)
  ,      bwd AS (PARTITION BY frame.attempt ORDER BY frame.level DESC)
)
SELECT * FROM gapfilled ORDER BY 2,1; -- UN-COMMENT TO TEST
SELECT
  attempt
, SUM(score) AS score_sum
FROM gapfilled
GROUP BY
  attempt;
-- out  attempt | score_sum 
-- out ---------+-----------
-- out        1 |        11
-- out        2 |        14
-- out        3 |        15

© www.soinside.com 2019 - 2024. All rights reserved.