0% found this document useful (0 votes)
473 views

SQL Exam

The document describes several examples of SQL queries and issues the author is having with writing queries to analyze data in different tables. In one example, the author wants a query that returns the difference between the latest and second latest value for each event type that occurs more than once. Another example wants to return recipients that received a total amount over 1024 from 3 or fewer transfers. A third example wants the most recent value for each sensor ID and event type.

Uploaded by

leo Lo
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
473 views

SQL Exam

The document describes several examples of SQL queries and issues the author is having with writing queries to analyze data in different tables. In one example, the author wants a query that returns the difference between the latest and second latest value for each event type that occurs more than once. Another example wants to return recipients that received a total amount over 1024 from 3 or fewer transfers. A third example wants the most recent value for each sensor ID and event type.

Uploaded by

leo Lo
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 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.
-
1d e.g.,
ow
n
vot
e
favorite

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


vote8dow their top 3 amounts received, then grouping by recipient returning
n vote those having sum(amount)>=1024
select recipient as account_name
accept ed

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;

You might also like