为什么我的查询在 Codility 的测试编辑器上返回错误?

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

我在 SQLite 中对 Codility / 练习 6 SQL / SqlEventsDelta 的解决方案适用于本地数据库浏览器,但不适用于在线 Codility 测试编辑器。我该如何解决这个问题?我想使用我自己的 SQLite 代码:

WITH cte1 AS
(
    SELECT *, CASE WHEN e2.event_type = e2.prev THEN 0
                 WHEN e2.event_type = e2.next THEN 0
                 ELSE 1 END AS grp
    FROM (SELECT *, LAG(e1.event_type) OVER(ORDER BY (SELECT 1)) AS prev , LEAD(e1.event_type) OVER(ORDER BY (SELECT 1)) AS next FROM events e1) e2
)
,cte2 AS
(
    SELECT cte1.event_type, cte1.time, cte1.grp, cte1.value - LAG(cte1.value) OVER(ORDER BY cte1.event_type, cte1.time) AS value
    FROM cte1
    WHERE cte1.grp = 0
    ORDER BY cte1.event_type, cte1.time
)

SELECT c2.event_type, c2.value
FROM cte2 c2
WHERE (c2.event_type, c2.time) IN (
    SELECT c2.event_type, MAX(c2.time) AS time
    FROM cte2 c2
    GROUP BY c2.event_type)
GROUP BY c2.event_type
ORDER BY c2.event_type, c2.time

它在 DB Browser for SQLite Version 3.12.2 上运行,没有错误:

event_type | value
-----------+-----------
2          | -5
3          | 4

Execution finished without errors.
Result: 2 rows returned in 7ms

但是在 Codility 测试编辑器(SQLite 版本 3.11.0)上我收到错误:

| Compilation successful.

| Example test:   (example test)
| Output (stderr):
| error on query: ...
| ...
| ...,
| details: near "(": syntax error
| RUNTIME ERROR (tested program terminated with exit code 1)

Detected some errors.
sql sqlite lag lead over-clause
13个回答
6
投票

我尝试使用一种有点幼稚的方法。我知道由于有很多子查询,这对性能非常不利,但这里的问题是 PostgreSQL 的“DISTINCT ON”,但我得到了 100% 😃

希望你喜欢!

select distinct on (event_type) event_type, result * -1
from (select event_type, value, lead(value) over (order by event_type) - value result
      from (select *
            from events
            where event_type in (select event_type
                                 from events
                                 group by event_type
                                 having count(event_type) >= 2)
            order by event_type, time desc) a) b

3
投票
with data as (SELECT a.event_type, a.value, a.time,
 --Produce a virtual table that stores the next and previous values for each event_type.
LEAD(a.value,1) over (PARTITION by a.event_type ORDER by 'event_type', 'time' DESC) as recent_val,
LAG(a.value,1) over (PARTITION by a.event_type ORDER by 'event_type', 'time' DESC) as penult_val
   
    from events a
    
    JOIN (SELECT event_type 
            from events --Filter the initial dataset for duplicates. Store in correct order
                group by event_type HAVING COUNT(*) > 1 
                    ORDER by event_type) b
        
        on a.event_type = b.event_type) --Compare the virtual table to the filtered dataset

SELECT event_type, ("value"-"penult_val") as diff --Perform the desired arithematic
    from data 
    where recent_val is NULL --Filter for the most recent value

嗨,团队!这就是我的答案。它很大程度上是上述答案的混合体,但它读起来更简单,并且针对上下文进行了评论。作为一个新手,希望对其他新手有帮助。


2
投票
with deltas as (
  select distinct event_type, 
     first_value(value) over (PARTITION by event_type ORDER by time DESC) - 
     nth_value(value, 2) over (PARTITION by event_type ORDER by time DESC) as delta
    from events
)
select * from deltas where delta is not null order by 1;

0
投票

我在使用sqlite时也遇到同样的问题。 尝试在 PostgreSQL 中使用以下代码

with data as (select 
e.event_type,
e.value,
e.time,
lead(e.value,1) over (PARTITION by e.event_type order by e.event_type,e.time asc) as next_val,
lag (e.value,1) over (PARTITION by e.event_type order by e.event_type,e.time asc) as prev_val
from events e)
select distinct d.event_type, (d.value-d.prev_val) as diff
from 
events e,data d
where e.event_type = d.event_type
and d.next_val is null
and e.event_type in ( SELECT event_type
                        from data 
                        group by 
                        event_type
                        having count(1) > 1)
order by 1;

0
投票

添加另一个涉及自连接的答案 -

PostgreSQL

-- write your code in PostgreSQL 9.4

WITH TotalRowCount AS (
    SELECT
        event_type,
        COUNT(*) as row_count
    FROM events
    GROUP BY 1
),

RankedEventType AS (
    SELECT
        event_type,
        value,
        ROW_NUMBER() OVER(PARTITION BY event_type ORDER BY time) as row_num
    FROM events
)


SELECT
    a.event_type,
    a.value - b.value as value
FROM RankedEventType a
INNER JOIN TotalRowCount c
    ON a.event_type = c.event_type
INNER JOIN RankedEventType b
    ON a.event_type = b.event_type
WHERE 1 = 1
AND a.row_num = c.row_count
AND b.row_num = c.row_count - 1
ORDER BY 1

0
投票

没有嵌套查询,获得100%

with data as (
with count as (select event_type
                                 from events
                                 group by event_type
                                 having count(event_type) >= 2)
select e.event_type , e.value, e.time from events as e inner join count as r on e.event_type=r.event_type  order by e.event_type, e.time desc                               
)
select distinct on (event_type) event_type,
           value - (LEAD(value) over (order by event_type))  result from data

0
投票

一个子查询的解决方案

WITH diff AS
  (SELECT event_type,
          value,
          LEAD(value) OVER (PARTITION BY event_type
                            ORDER BY TIME DESC) AS prev
   FROM EVENTS
   GROUP BY event_type,
            value,
            time
)

SELECT DISTINCT ON (event_type) event_type,
                   value - prev
FROM diff
WHERE prev IS NOT NULL;

0
投票

--在 PostgreSQL 9.4 中

with ct1 as (SELECT 
    event_type,
    value,
    time,
    rank() over (partition by event_type order by time desc) as rank
from events),
ct2 as (
select event_type, value, rank, lag (value,1) over (order by event_type) as previous_value
from ct1
order by event_type)
select event_type, previous_value - value from ct2
where rank = 2
order by event_type

0
投票

--1) “极简”旧式解决方案(不使用窗口函数) WITH maxevents AS(选择 event_type 作为 Et1,max(time) 作为 maxtime from events 按 event_type 进行分组,其中 count(1)>1), 防止 AS(选择 event_type 作为 Et2,max(time) 作为 nextime 来自事件 JOIN maxevents ON event_type=Et1 AND time

选择 event_type,v1-v2 作为值 FROM maxeventvalues JOIN preveventvalues ON event_type=et 按 event_type asc 排序 ; --2) 使用窗口函数的现代解决方案 WITH maxevents AS(选择 event_type 为 Et1,max(time) 为 maxtime 来自按 event_type 划分的事件组,其中 count(1)>1) ,AllValDifs as (SELECT event_type, value- LAG(value,1,0) OVER (PARTITION BY event_type ORDER BY time ASC) as ValDif , time FROM 事件 JOIN maxevents ON event_type=et1) 选择不同的事件类型,FIRST_VALUE(ValDif)
来自 AllValDifs 的 OVER (PARTITION BY event_type ORDER BY time DESC) 按事件类型 ASC 排序;


0
投票

我的解决方案:

通过

event_type
获取排名1、2的表格:

with t2 as(
select event_type, value, rank from (
    select event_type, value,
        rank() over(
        partition by event_type
        order by time desc) as rank,
        count(*) over (partition by event_type) as count
    from events) as t
where t.rank <= 2 and t.count > 1
)

使用

Lead()
计算差异并使用
max
过滤掉空差异:

select t3.event_type, max(t3.diff) from (
    select event_type, 
    value - lead(value, 1) over (
        partition by event_type
        order by rank) as diff
    from t2) as t3
group by t3.event_type

0
投票

我在 MSSQL 上尝试了这个,它也有效

 SELECT event_type, 
        MAX(value) - MAX(prev_value) AS value_difference
 FROM (
        SELECT event_type, 
               value, 
               L.AG(value) OVER (PARTITION BY event_type ORDER BY time) AS prev_value
        FROM events) AS subquery
 GROUP BY event_type
 HAVING COUNT(*) > 1
 ORDER BY event_type;

0
投票

我能够用这种方式解决它:

select
    event_type
    ,delta
from ( 
    select
        *
        ,rn_calc - lead(value) over(partition by event_type order by rn asc)    delta
    from (
        select 
            event_type
            ,max(value) over(partition by event_type order by time desc)            rn_calc
            ,row_number() over(partition by event_type order by time desc)          rn
            ,value
            --,time
        from events
    ) t
    where rn in (1,2)
) t
where rn = 1 and delta is not null

0
投票

这可以简单地通过

来完成
WITH ranked_event AS (
    SELECT
      event_type,
      value, 
      time,
      ROW_NUMBER() OVER (PARTITION BY event_type ORDER BY time DESC) AS row_num
   FROM events
)

SELECT 
  e1.event_type,
  e1.value - e2.value AS value_difference
FROM ranked_event AS e1
INNER JOIN ranked_event AS e2
  ON e1.event_type = e2.event_type
  AND e1.row_num = 1 AND e2.row_num = 2
ORDER BY e1.event_type
© www.soinside.com 2019 - 2024. All rights reserved.