Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.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查询玩家的平均连胜持续时间_Sql_Oracle - Fatal编程技术网

SQL查询玩家的平均连胜持续时间

SQL查询玩家的平均连胜持续时间,sql,oracle,Sql,Oracle,假设我有一个包含三列和以下数据的表: * gamedate,playername,pointsScored * 20180101,George,34 * 20180102,George,37 * 20180103,George,38 * 20180104,George,3 * 20180105,George,35 * 20180106,George,37 * 20180107,George,31 * 20180108,George,31 * 20180109,George,32 * 201801

假设我有一个包含三列和以下数据的表:

* gamedate,playername,pointsScored
* 20180101,George,34
* 20180102,George,37
* 20180103,George,38
* 20180104,George,3
* 20180105,George,35
* 20180106,George,37
* 20180107,George,31
* 20180108,George,31
* 20180109,George,32
* 20180110,George,7
我正在寻找一个
sql查询
,它告诉我这个玩家平均可以在一行中保持多少个30+的分数。我知道它必须是某种
groupby
函数,但我一直在思考如何表述这个查询。这是一个
Oracle表
,如果这有什么区别的话

一些额外的测试日期:

with
inputs(gamedate,playername,pointsscored) as (
select to_date('20180912','yyyymmdd'), 'George',52 from dual union all
select to_date('20180907','yyyymmdd'), 'George',47 from dual union all
select to_date('20180829','yyyymmdd'), 'George',9 from dual union all
select to_date('20180823','yyyymmdd'), 'George',55 from dual union all
select to_date('20180818','yyyymmdd'), 'George',49 from dual union all
select to_date('20180811','yyyymmdd'), 'George',58 from dual union all
select to_date('20180805','yyyymmdd'), 'George',31 from dual union all
select to_date('20180730','yyyymmdd'), 'George',40 from dual union all
select to_date('20180720','yyyymmdd'), 'George',44 from dual union all
select to_date('20180712','yyyymmdd'), 'George',45 from dual union all
select to_date('20180707','yyyymmdd'), 'George',29 from dual union all
select to_date('20180701','yyyymmdd'), 'George',-5 from dual union all
select to_date('20180626','yyyymmdd'), 'George',46 from dual union all
select to_date('20180620','yyyymmdd'), 'George',22 from dual union all
select to_date('20180614','yyyymmdd'), 'George',49 from dual union all
select to_date('20180609','yyyymmdd'), 'George',40 from dual union all
select to_date('20180602','yyyymmdd'), 'George',40 from dual
)

这里有一个方法。它使用Tabibitosan(或“固定差异”)方法来识别条纹-这是内部查询中两个行号调用的差异。其余的是分组和使用聚合函数

WITH子句用于模拟数据;它不是解决方案的一部分,在实际数据上测试解决方案之前,应将其删除。(使用实际的表名,而不是内部查询中的输入。)

输出

PLAYER AVERAGE_STREAK
------ --------------
George              4

在Oracle 12.1或更高版本中,
MATCH\u RECOGNIZE
子句可以快速完成此类赋值:

with
  inputs(gamedate,playername,pointsscored) as (
    select to_date('20180101','yyyymmdd'), 'George', 34 from dual union all
    select to_date('20180102','yyyymmdd'), 'George', 37 from dual union all
    select to_date('20180103','yyyymmdd'), 'George', 38 from dual union all
    select to_date('20180104','yyyymmdd'), 'George',  3 from dual union all
    select to_date('20180105','yyyymmdd'), 'George', 35 from dual union all
    select to_date('20180106','yyyymmdd'), 'George', 37 from dual union all
    select to_date('20180107','yyyymmdd'), 'George', 31 from dual union all
    select to_date('20180108','yyyymmdd'), 'George', 31 from dual union all
    select to_date('20180109','yyyymmdd'), 'George', 32 from dual union all
    select to_date('20180109','yyyymmdd'), 'George',  7 from dual
  )
select playername, avg(cnt) as average_streak
from   inputs
match_recognize(
  partition by playername
  order by     gamedate
  measures     count(*) as cnt
  one row per match
  pattern ( a+ )
  define a as pointsscored >= 30
)
group by playername
;

PLAYER AVERAGE_STREAK
------ --------------
George              4
说明:


MATCH\u RECOGNIZE
按玩家对输入行进行分区,并按游戏日期在每个分区内排序。“匹配”是一个或多个连续行(在
模式
子条款中的
A+
)的出现,得分为30分或以上(见
定义
子条款)
MATCH\u RECOGNIZE
为找到的每一场比赛返回一行,特别是返回球员姓名和比赛中的行数(即连胜长度、连续行数或比赛)。外部查询按玩家分组,并获取平均连胜长度。

试图了解问题。。。在你的样本中,我们是不是在看两连胜,一场是三场比赛,另一场是五场比赛,而你要找的平均数是4?不管在两块牛排之间,或者在第一块牛排之前,或者在最后一块牛排之后,有多少场得分低于30分的比赛?是的,mathguy,没错,你知道你的答案翻了一倍吗?朋友:)mathguy,非常感谢你!!这正是我需要的。查询是如此简单@BarbarosÖzhan——我想你不是真的想说我“加倍”了答案(意思是,两次发布了相同的答案)。相反,我对同一个问题给出了两个答案。是的,我知道——有时我会这样做,当我对同一个问题提供两个完全不同且不相关的答案时(通常,一个答案可能更好,但只适用于最新版本的Oracle)。据我所知,这应该是可以的。是的,我指的是第二种情况“同一个问题的两个答案”。mathguy我能够运行这个查询,但它没有给我一些数据集的预期答案。我用我用来测试的数据更新了我的问题。@themosquito-我刚刚用新数据运行了这个查询。我得到的结果是3.25,这是正确的:有四条条纹,长度分别为2、7、1和3。13/4 = 3.25,或者你认为一个“条纹”长度1(一个游戏超过30分,在两个游戏少于30分)作为“不是条纹”?在这两种解决方案中,我认为这是一条长度为1的条纹。如果一场30分以上的比赛不是连胜,那么两个查询都必须修改,并且对于这个不同的定义,两个查询都可以很容易地修改。(还有,乔治真的在一场比赛中得了负五分吗?)。但是你是对的答案应该是3.25。是的,乔治确实在一场比赛中得了-5分。因此,我好奇的是,一个通常得分超过40分的优秀球员,每3场或4场比赛就有一场糟糕的比赛。而且糟糕的比赛不会与更强硬的对手排成一行。因此,我想对数据进行一些分析,看看平均有多少场好比赛可以让他和其他处于他位置的球员在输掉一场糟糕的比赛之前保持连胜@默基多-一个球员,任何球员,怎么能得分为负数?你是说他得了5分吗?得了-5分意味着什么?在足球比赛中,也许你会把自己的进球算作消极进球;这对篮球意味着什么?
with
  inputs(gamedate,playername,pointsscored) as (
    select to_date('20180101','yyyymmdd'), 'George', 34 from dual union all
    select to_date('20180102','yyyymmdd'), 'George', 37 from dual union all
    select to_date('20180103','yyyymmdd'), 'George', 38 from dual union all
    select to_date('20180104','yyyymmdd'), 'George',  3 from dual union all
    select to_date('20180105','yyyymmdd'), 'George', 35 from dual union all
    select to_date('20180106','yyyymmdd'), 'George', 37 from dual union all
    select to_date('20180107','yyyymmdd'), 'George', 31 from dual union all
    select to_date('20180108','yyyymmdd'), 'George', 31 from dual union all
    select to_date('20180109','yyyymmdd'), 'George', 32 from dual union all
    select to_date('20180109','yyyymmdd'), 'George',  7 from dual
  )
select playername, avg(cnt) as average_streak
from   inputs
match_recognize(
  partition by playername
  order by     gamedate
  measures     count(*) as cnt
  one row per match
  pattern ( a+ )
  define a as pointsscored >= 30
)
group by playername
;

PLAYER AVERAGE_STREAK
------ --------------
George              4