Você está na página 1de 5

1.

The structure of the table is like

create table events(


event_type integer not null,
value integer not null,
time timestamp not null,
unique (event_type ,time)
);
Have inserted few values like

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')
I want to write a query that for each event_type that has been registered more than once
returns the difference between the latest and the second latest value .

Given the above data, the output should be like

event_type value
2 -5
3 4
I can bring out the lowest and the highest using below queries . This is how far I could reach
..confused on the way further .

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 ;

SELECT a.event_type,
(b.value - a.value) AS value
FROM (SELECT *
FROM events
GROUP BY event_type, time, value
ORDER BY time ASC
LIMIT 2 OFFSET 1) AS a ,
(SELECT *
FROM events
GROUP BY event_type, time, value
ORDER BY time DESC
LIMIT 2 OFFSET 0) AS b
WHERE a.event_type IN ( SELECT e.event_type
FROM events e
GROUP BY e.event_type
HAVING COUNT(e.event_type) >= 2 )
AND a.event_type = b.event_type
ORDER BY a.event_type ASC
2. I want to have a sql that gives recipient that received of amount >= 1024, with
number of transfer <=3.
-
1do e.g.,
wn
vote
avorite
f

The result is:

Johnson is listed since Johnson account is listed because it has received 1112
USD in the following three transfers: 512 USD + 100 USD + 500 USD, Taylor is
with 1 transfer of USD 1024. Williams is not there since he receives 1200 in four
transactions.

Select recipient as account_name from transfers group by recipient


having sum(amount)>=1024 and count(amount)<=3
It doesn't work correctly. I am using PostgreSQL, SQLLites syntax is fine too.

Attached is the table and row creation for your convenient

create table transfers (


sender varchar(1000) not null,
recipient varchar(1000) not null,
date date not null,
amount integer not null
);

insert into transfers values('Smith','Taylor',convert(date,'2002-09-27'),'1024')


insert into transfers values('Smith','Johnson',convert(date,'2005-06-26'),'512')
insert into transfers values('Williams','Johnson',convert(date,'2010-12-17'),'100')
insert into transfers values('Williams','Johnson',convert(date,'2004-03-22'),'10')
insert into transfers values('Brown','Johnson',convert(date,'2013-03-20'),'500')
insert into transfers values('Johnson','Williams',convert(date,'2007-06-02'),'400')
insert into transfers values('Johnson','Williams',convert(date,'2005-06-26'),'400')
insert into transfers values('Johnson','Williams',convert(date,'2005-06-26'),'200')
sql postgresql sqlite
shareimprove this question edited Mar 6 at 14:38 asked Mar 5 at 13:37

Servy william007
167k18207309 4,10773675

1 Your SQL means that the person has had 3 or less transactions, not that the amount of 3 or less is more than
1024 – James Z Mar 5 at 13:40
add a comment
3 Answers
activeoldest votes

up using row_number() and a derived table to limit each recipient to their top 3
vote8down amounts received, then grouping by recipient returning those
vote having sum(amount)>=1024
select recipient as account_name
accepted

from (
select *
, row_number() over (
partition by recipient
order by amount desc
) as rn
from transfers
) as i
where rn < 4
group by recipient
having sum(amount)>=1024
returns:

+--------------+
| account_name |
+--------------+
| Johnson |
| Taylor |
+--------------+
rextester postgres demo: http://rextester.com/PFR74297

The question was edited that removed some pertinent information from
the 3rd revision of the question: what was tried already.
I try

Select recipient as account_name from transfers group by recipient


having sum(amount)>=1024 and count(amount)<=3
It doesn't work correctly.
Based on that information, I concluded that OP wanted to find recipients that
received a sum(amount)>=1024 from 3 or fewer of any of that recipient's
transfers -- not limited to those recipients with 3 or fewer transfers
and sum(amount)>=1024.
SELECT recipient AS account_name FROM
(
SELECT transfers.recipient, SUM(transfers.amount) AS amountsum FROM transfers
WHERE transfers.rowid IN (
SELECT tmp.rowid FROM transfers tmp
WHERE transfers.recipient = tmp.recipient
ORDER BY tmp.amount DESC
LIMIT 3
)
GROUP BY transfers.recipient
)
WHERE amountsum >= 1024;

3.
create table events (
sensor_id integer not null,
event_type integer not null,
value integer not null,
time timestamp unique not null);

insert into events


values
(2,2,5,"2014-02-13 12:42:00"),
(2,4,-42,"2014-02-13 13:19:57"),
(2,2,2,"2014-02-13 14:48:30"),
(3,2,7,"2014-02-13 12:54:39"),
(2,3,54,"2014-02-13 13:32:36");
I want for each sensor_id and event_type only the most recent value in terms of time

expected result

sensor_id, event_type value


2 2 2
2 3 54
2 4 -42
3 2 7

select sensor_id,event_type,value, time

from events

where time in (select max(time) from events group by sensor_id, event_type)

SELECT
E1.SENSOR_ID,
COUNT(E1.EVENT_TYPE) AS "TYPES"
FROM
(
SELECT
DISTINCT
E.SENSOR_ID,
E.EVENT_TYPE
FROM
EVENTS E
) E1
GROUP BY E1.SENSOR_ID
ORDER BY E1.SENSOR_ID ASC

SELECT e.sensor_id, e.event_type, e.value, e.time


from events e join
(select sensor_id, event_type, max(time) as maxt
from events e
group by sensor_id, event_type
) ee
on e.sensor_id = ee.sensor_id and e.event_type = ee.event_type;

Você também pode gostar