表的结构类似于
insert into events values
(2, 5, '2015-05-09 12:42:00'),
(4, -42, '2015-05-09 13:19:57'),
(2, 2, '2015-05-09 14:48:39'),
(2, 7, '2015-05-09 13:54:39'),
(3, 16, '2015-05-09 13:19:57'),
(3, 20, '2015-05-09 15:01:09')
插入了一些值,例如
event_type value
2 -5
3 4
我想写一个查询,对于已经多次注册的每个event_type,返回最新值和第二个最新值之间的差值。
鉴于以上数据,输出应该像
select event_type,value,time from events group by event_type order by event_type desc;
select * from events group by event_type order by event_type ;
我可以使用以下查询显示最低和最高。这是我可以达到的距离..在进一步的方式上融合。
import javax.swing.JOptionPane;
public class WhileEx {
public static void main(String[] args){
int start = Integer.parseInt(JOptionPane.showInputDialog("Enter a starting number (integer)"));
int end = Integer.parseInt(JOptionPane.showInputDialog("Enter an ending number (integer)"));
while (start < end)
{
start = start * 4;
System.out.print (start + " ");
}
}
}
答案 0 :(得分:7)
我没有看到与MySQL或PostgreSQL相关的答案。所以,这是我的方法,以及MySQL / PostgreSQL的工作解决方案:
resources
答案 1 :(得分:6)
我从Shadkhan修改/简化了解决方案。适用于MySQL,Sqlite,PostgreSQL
SELECT e1.event_type, (e1.value - e2.value) AS value FROM
events e1
JOIN
events e2
ON
e1.event_type = e2.event_type
AND
e1.time = (SELECT time FROM events temp1 WHERE
temp1.event_type=e1.event_type ORDER BY time DESC LIMIT 1)
AND
e2.time = (SELECT time FROM events temp2 WHERE
temp2.event_type=e2.event_type ORDER BY time DESC LIMIT 1 OFFSET 1)
答案 2 :(得分:3)
当作者问我如何在SQL Server或Oracle中执行此操作时,这里的解决方案应该适用于它们(不是在MYSQL中):
with cte1 as (
select e.event_type,
value - lead(value,1) over (partition by e.event_type order by time desc) value,
row_number() over (partition by e.event_type order by time desc) xrow
from t_events e
)
select event_type, value from cte1
where xrow = 1 and value is not null
这是小提琴: http://www.sqlfiddle.com/#!4/9271a/19
我所做的是使用聚合函数按日期排序行(使用row_number
函数)并计算当前行和下一行之间的差异(使用lead
函数)。准备好之后,我只需要删除不再需要的行。
我不得不更改创建并为Oracle插入一点(并且可能需要对SQL Server进行另一次调整),但select语句应该适用于它们。
答案 3 :(得分:2)
首先我尝试使用两个以上的记录来获取每个event_type
(SELECT e.event_type
from events e
group by e.event_type
having count(e.event_type)>=2
) g --get more than equals two records
之后获取每个event_type中的第一条记录
(select r.event_type, r.value
from (SELECT ROW_NUMBER() OVER (PARTITION BY e.event_type ORDER BY time Desc) AS Group_id,e.*
from g left join events e on g.event_type= e.event_type
order by e.event_type
)r
where r.Group_id =1 -- get first row of group
)row1
之后在每个event_type中获取第二条记录
(select r.event_type, r.value
from (SELECT ROW_NUMBER() OVER (PARTITION BY e.event_type ORDER BY time Desc) AS Group_id,e.*
from g left join events e on g.event_type= e.event_type
order by e.event_type
)r
where r.Group_id =2 -- get second row of group
)row2
最后加入最后两个查询来计算答案
select row1.event_type , row1.value -row2.value
from row1 join row2 on row1.event_type= row2.event_type
最后的答案是:
select row1.event_type , row1.value -row2.value
from (select r.event_type, r.value
from (SELECT ROW_NUMBER() OVER (PARTITION BY e.event_type ORDER BY time Desc) AS Group_id,e.*
from (SELECT e.event_type
from events e
group by e.event_type
having count(e.event_type)>=2
) g --get more than equals two records
left join events e on g.event_type= e.event_type
order by e.event_type
)r
where r.Group_id =1
)row1--get first records in each groups
join
(select r.event_type, r.value
from (SELECT ROW_NUMBER() OVER (PARTITION BY e.event_type ORDER BY time Desc) AS Group_id,e.*
from (SELECT e.event_type
from events e
group by e.event_type
having count(e.event_type)>=2
) g --get more than equals two records
left join events e on g.event_type= e.event_type
order by e.event_type
)r
where r.Group_id =2
)row2--get Second records in each groups
on row1.event_type= row2.event_type
答案 4 :(得分:2)
这是我的查询,
SELECT a.event_type as event_type,
a.value-b.value as diff_value
FROM
(SELECT e1.*
FROM EVENTS e1,
(SELECT event_type,
max(TIME) AS TIME
FROM EVENTS
GROUP BY event_type
HAVING count(event_type) > 1) MAX
WHERE e1.event_type = max.event_type
AND e1.time = max.time) a,
( SELECT e1.*
FROM EVENTS e1,
(SELECT e1.event_type,
max(e1.time) AS TIME
FROM EVENTS e1,
(SELECT event_type,
max(TIME) AS TIME
FROM EVENTS
GROUP BY event_type
HAVING count(event_type) > 1) MAX
WHERE e1.event_type = max.event_type
AND e1.time < max.time
GROUP BY e1.event_type) max2
WHERE e1.event_type = max2.event_type
AND e1.time = max2.time ) b
WHERE a.event_type = b.event_type
旁注:
a是最大值,
b是第二最大值
使用https://sqliteonline.com/创建表并派生上述查询。
答案 5 :(得分:1)
<强>计划强>
- 使用滞后变量来计算相同事件类型的值差异(使用良好的顺序)
- 过滤值,其中值差异为非空
醇>
<强>查询强>
set @rnk := 0;
set @lag_ev := null;
set @lag_va := null;
select lagged.event_type, lagged.diff_val as value_difference
from
(
select ev.*,
case when @lag_ev is not null and @lag_ev = event_type
then @rnk := @rnk + 1
else @rnk := 0
end as rnk,
case when @rnk = 1
then @lag_va - value
else null
end as diff_val,
@lag_ev := event_type as lag_ev,
@lag_va := value as lag_va
from events ev
order by event_type, time desc
) lagged
where lagged.diff_val is not null
order by lagged.value
;
<强>输出强>
+------------+----------+
| event_type | diff_val |
+------------+----------+
| 2 | -5 |
| 3 | 4 |
+------------+----------+
答案 6 :(得分:0)
试试这个,
;WITH CTE
AS (SELECT event_type,
value,
time,
Row_number()
OVER(
PARTITION BY event_type
ORDER BY event_type) AS RN
FROM #t_events)
SELECT A.event_type,
( A.value - B.value ) AS Value
FROM (SELECT *
FROM CTE
WHERE RN = 1)A
JOIN (SELECT *
FROM CTE
WHERE RN = 2)B ON A.event_type = B.event_TYPE
答案 7 :(得分:0)
<application>
<receiver android:name="my_receiver" />
</application>
<permission android:name="name"
android:label="my_permission"
android:protectionLevel="signature">
<uses-permission android:name="name"/>
答案 8 :(得分:0)
对于MySQL
SELECT ee.event_type,(ee.value - e1.value) AS VALUE
FROM (
SELECT * FROM `events` e GROUP BY e.event_type HAVING COUNT(e.event_type) > 1) AS t
JOIN `events` ee ON ee.event_type = t.event_type
AND ee.time = (SELECT MAX(eee.time)
FROM `events` eee WHERE eee.event_type = ee.event_type ORDER BY eee.time DESC LIMIT 1)
JOIN `events` e1 ON e1.event_type = t.event_type
AND e1.time = (SELECT e2.time
FROM `events` e2 WHERE e2.event_type = e1.event_type ORDER BY e2.time DESC LIMIT 1,1);
答案 9 :(得分:0)
我会这样做:D
WITH CTE AS
(
SELECT event_type
,val
,timee
,ROW_NUMBER() OVER ( PARTITION BY event_type ORDER BY Timee DESC) AS Stamp
FROM eventss2
--ORDER BY price
)
SELECT event_type
,SUM (CASE WHEN Stamp=1 THEN val ELSE val*-1 END ) AS 'pricedif'
FROM CTE
WHERE Stamp<=2
GROUP BY event_type
HAVING SUM(stamp)>1
答案 10 :(得分:0)
我从 SQLite 提出了这样的解决方案。
drop table if exists events;
create table events(event_type integer not null,
value integer not null, time timestamp not null,
unique(event_type, time));
insert into events
values(2, 5, '2015-05-09 12:42:00'), (4, -42, '2015-05-09 13:19:57'),
(2, 2, '2015-05-09 14:48:39'), (2, 7, '2015-05-09 13:54:39'),
(3, 16, '2015-05-09 13:19:57'), (3, 20, '2015-05-09 15:01:09');
select event_type,
sum(
case num when 1 then 1 when 2 then - 1
else 0 end * value) value
from(select row_number() over(partition by event_type order by time desc) num, *
from events)
group by event_type
having count() > 1
答案 11 :(得分:0)
使用公用表表达式:
WITH evt AS
(
select
event_type,
value,
rank() over(partition by event_type order by time desc) rnk
from events
)
select
t1.event_type, t1.value - t2.value
from evt t1, evt t2
where t1.event_type = t2.event_type
and t1.rnk = 1
and t2.rnk = 2
没有任何 CTE
select t1.event_type, t1.value - t2.value from
(
select
event_type,
value,
rank() over(partition by event_type order by time desc) rnk
from events
)t1,
(
select
event_type,
value,
rank() over(partition by event_type order by time desc) rnk
from events
)t2
where t1.event_type = t2.event_type
and t1.rnk = 1
and t2.rnk = 2
;
答案 12 :(得分:-1)
with CteEvt
as
(
SELECT
event_type,
value,
time,
dense_rank() over (partition by event_type order by time desc) as rnk
from events
order by event_type
)
select c1.event_type,
(c1.value- (case when c2.value is null then 0 else c2.value end)) as value
from CteEvt c1
inner join CteEvt c2 on c1.event_type=c2.event_type and c2.rnk=2
where c1.rnk=1