Reputation: 608
This gives me all the records for a particular switch and port. I would like to delete all except the first and last one for each day.
/mysql -sN --user=root --password=notmypassword -e
"SELECT * FROM collector.fibre
WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND (time > '2016-05-31 00:00:00' AND time < '2016-05-31 23:59:59') "
Upvotes: 0
Views: 1898
Reputation: 14721
I don't know how much time will it take to delete all this records but i think minutes of works just wait for it :
delete fb from collector.fibre fb
INNER JOIN
(
SELECT
distinct
f.id -- extract only the ids
FROM
collector.fibre f
INNER JOIN (
-- create a special table day min_time max_time
select
date(time) as 'day',
min(time) as 'min_time',
max(time) as 'max_time'
from
collector.fibre
Where
-- must be the same set of records
-- because we look for a dates of this switch
fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
group by date(time)
) fd on date(f.time) = fd.day -- join the two table to have a special table see example down
WHERE
fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
-- extract record witch the time is not
-- the min or the max of that date
AND (f.time <> fd.min_time and f.time <> fd.max_time)
) recs on fb.id = recs.id -- join the table and the result of query by the id now you will remove the records that exist in the result of the query
Upvotes: 2
Reputation: 1203
Give this a try:
DELETE
FROM collector.fibre
WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND time BETWEEN '2016-05-31 00:00:00' AND '2016-05-31 23:59:59'
AND time NOT IN (
SELECT MIN(time), MAX(time)
FROM collector.fibre
WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND time BETWEEN '2016-05-31 00:00:00' AND '2016-05-31 23:59:59'
)
Upvotes: 0
Reputation: 22760
by "first and last" I will assume you mean earliest and latest, so:
It is assumed your time is stored in a
DATETIME
column.
DELETE FROM collector.fibre
WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND (TIME(time) !=
(
SELECT MAX(TIME(time))
FROM `collector`.`fibre` WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND DATE(time) = '2016-05-30'
)
AND
TIME(time) != (
SELECT MIN(TIME(time))
FROM `collector`.`fibre` WHERE fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
AND DATE(time) = '2016-05-30'
)
)
AND DATE(time) = '2016-05-30'
This is probably poorly written and does unfortunately use criteria repetition for the subqueries but the concept works as:
SubSelect by criteria and Not rows where the time column is MAX or MIN time values fitting said criteria
Reference : https://stackoverflow.com/a/7836444/3536236
So you can then input each day and remove non-earliest and non-latest values. If you want to cycle through the whole table in one fell swoop I would figure you want to create a Procedure
but I don't know enough to help you much here. However your title says MYSQL delete all records except first and last for a given date
which implies you will manually run it one date at a time as needed.
Example Set:
fabric_switch_name | datatype | port | time ------------------------------------------------------------------- switch-1 | TxElements | 2 | 2016-05-31 15:00:00 switch-1 | TxElements | 1 | 2016-05-30 22:10:00 switch-2 | TxElements | 0 | 2016-05-30 15:00:00 switch-1 | TxElements | 0 | 2016-05-29 10:20:10 switch-1 | TxElements | 0 | 2016-05-29 05:50:00 switch-1 | TxElements | 0 | 2016-05-29 19:50:00 switch-1 | TxElements | 5 | 2016-05-29 21:50:00 switch-1 | TxElements | 0 | 2016-05-29 20:11:40
Result Set:
fabric_switch_name | datatype | port | time ------------------------------------------------------------------- switch-1 | TxElements | 2 | 2016-05-31 15:00:00 switch-1 | TxElements | 1 | 2016-05-30 22:10:00 switch-1 | TxElements | 0 | 2016-05-29 05:50:00 switch-2 | TxElements | 0 | 2016-05-30 15:00:00 switch-1 | TxElements | 5 | 2016-05-29 21:50:00 switch-1 | TxElements | 0 | 2016-05-29 20:11:40
Upvotes: 1
Reputation: 14721
this query will extract all the record that should be deleted :
SELECT
*
FROM
collector.fibre f
INNER JOIN (
-- create a special table day min_time max_time
select
date(time) as 'day',
min(time) as 'min_time',
max(time) as 'max_time'
from
collector.fibre
Where fabric_switch_name = 'switch-1'
group by date(time)
) fd on date(f.time) = fd.day -- join the two table to have a special table see example down
WHERE
fabric_switch_name = 'switch-1'
AND port = '0'
AND datatype = 'TxElements'
-- extract record witch the time is not
-- the min or the max of that date
AND (f.time <> fd.min_time and f.time <> fd.max_time)
let suppose this is your date
1 2016-05-31 23:00:00
2 2016-05-31 01:00:00
3 2016-05-31 00:00:00
4 2016-05-30 10:00:12
5 2016-05-30 01:00:00
6 2016-05-30 00:05:00
the result of join :
1 2016-05-31 23:00:00 2016-05-31 2016-05-31 00:00:00 2016-05-31 23:00:00 -- this will not be selected in the result
2 2016-05-31 01:00:00 2016-05-31 2016-05-31 00:00:00 2016-05-31 23:00:00 -- this will be selected because it's not min or max of that day
3 2016-05-31 00:00:00 2016-05-31 2016-05-31 00:00:00 2016-05-31 23:00:00
4 2016-05-30 10:00:00 2016-05-30 2016-05-30 00:05:00 2016-05-30 10:00:12
5 2016-05-30 01:00:00 2016-05-30 2016-05-30 00:05:00 2016-05-30 10:00:12
6 2016-05-30 00:00:00 2016-05-30 2016-05-30 00:05:00 2016-05-30 10:00:12
Upvotes: 0