Codility SqlEventsDelta(计算每种事件类型的最新值和第二最新值之间的差异)
Codility SqlEventsDelta (Compute the difference between the latest and the second latest value for each event type)
最近在Codility中练习代码练习。
在这里你可以找到问题,它在练习 6 - SQL 部分。
刚开始测试看问题描述! SqlEventsDelta
问题定义:
我在 SQLite 中针对 SqlEventDelta 问题编写了此解决方案。它在本地工具中工作正常但是,它在网络工具中不起作用。
任何人都可以就如何解决这个问题提供任何建议吗?
※ 我在 Whosebug 上搜索了这个问题,我知道比我自己的方法更好的代码。
但是,如果可能的话,我想使用我自己的 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
但是,在 web 工具(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.
SqlEventDelta 问题:
编写一个 SQL 查询,对于每个已注册超过一次的 event_type,return 是最新(即最近的时间)之间的差异) 和第二个最新值。
- table 应按 event_type 排序(升序)。
- 行集中列的名称无关紧要,但它们的顺序很重要。
给定一个 table 事件 具有以下结构:
create table events (
event_type integer not null,
value integer not null,
time timestamp not null,
unique(event_type, time)
);
例如,给定以下 数据:
event_type | value | time
-----------+------------+--------------------
2 | 5 | 2015-05-09 12:42:00
4 | -42 | 2015-05-09 13:19:57
2 | 2 | 2015-05-09 14:48:30
2 | 7 | 2015-05-09 12:54:39
3 | 16 | 2015-05-09 13:19:57
3 | 20 | 2015-05-09 15:01:09
鉴于上述数据,输出 应该return 以下行集:
event_type | value
-----------+-----------
2 | -5
3 | 4
谢谢。
我试图使用一种有点幼稚的方法。我知道由于有很多子查询,这对性能非常不利,但这里的问题是 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
我在使用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;
添加另一个涉及自连接的答案 -
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
没有嵌套查询,得到 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
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
大家好!这是我的答案。它主要是上面答案的糊涂集团,但它读起来更简单,并且针对上下文进行了评论。作为新手,希望对其他新手有所帮助
最近在Codility中练习代码练习。 在这里你可以找到问题,它在练习 6 - SQL 部分。 刚开始测试看问题描述! SqlEventsDelta
问题定义:
我在 SQLite 中针对 SqlEventDelta 问题编写了此解决方案。它在本地工具中工作正常但是,它在网络工具中不起作用。
任何人都可以就如何解决这个问题提供任何建议吗?
※ 我在 Whosebug 上搜索了这个问题,我知道比我自己的方法更好的代码。 但是,如果可能的话,我想使用我自己的 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
但是,在 web 工具(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.
SqlEventDelta 问题:
编写一个 SQL 查询,对于每个已注册超过一次的 event_type,return 是最新(即最近的时间)之间的差异) 和第二个最新值。
- table 应按 event_type 排序(升序)。
- 行集中列的名称无关紧要,但它们的顺序很重要。
给定一个 table 事件 具有以下结构:
create table events (
event_type integer not null,
value integer not null,
time timestamp not null,
unique(event_type, time)
);
例如,给定以下 数据:
event_type | value | time
-----------+------------+--------------------
2 | 5 | 2015-05-09 12:42:00
4 | -42 | 2015-05-09 13:19:57
2 | 2 | 2015-05-09 14:48:30
2 | 7 | 2015-05-09 12:54:39
3 | 16 | 2015-05-09 13:19:57
3 | 20 | 2015-05-09 15:01:09
鉴于上述数据,输出 应该return 以下行集:
event_type | value
-----------+-----------
2 | -5
3 | 4
谢谢。
我试图使用一种有点幼稚的方法。我知道由于有很多子查询,这对性能非常不利,但这里的问题是 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
我在使用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;
添加另一个涉及自连接的答案 -
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
没有嵌套查询,得到 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
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
大家好!这是我的答案。它主要是上面答案的糊涂集团,但它读起来更简单,并且针对上下文进行了评论。作为新手,希望对其他新手有所帮助