I want to delete data between 'change_slot' and ('change_slot' + 2min) WHERE type = ' crash', 'pilot_death', or 'eject'
DELETE FROM pe_LogEvent
WHERE pe_LogEvent_type = 'crash'
OR pe_LogEvent_type = 'pilot_death'
OR pe_LogEvent_type = 'eject'
AND pe_LogEvent_datetime IN??? pe_LogEvent_type = 'change_slot'
BETWEEN ('change_slot datetime') AND (DATE_ADD('change_slot datetime', INTERVAL 120)))
Visual SQL DB Image with annotation of what I am trying to accomplish.:
I have another issue now, I'm trying to think of a way to solve this one as well. I was trying to use maybe a 'for each' iterative statement to filter only 1 pilotname at a time maybe? How would you go about solving this?
Problem: different pilot change_slot and causes current pilot's death not to count now ... I need to only have same pilot change_slot within 2 min pilot_death, crash, or eject does not count
DELETE FROM pe_LogEvent
WHERE pe_LogEvent_datetime BETWEEN
(SELECT pe_LogEvent_datetime FROM pe_LogEvent WHERE pe_LogEvent_type = 'change_slot' ORDER BY pe_LogEvent_datetime DESC LIMIT 1)
AND (SELECT pe_LogEvent_datetime + INTERVAL 2 MINUTES FROM pe_LogEvent WHERE pe_LogEvent_type = 'change_slot' ORDER BY pe_LogEvent_datetime DESC LIMIT 1)
AND pe_LogEvent_type IN ('crash', 'pilot_death', 'eject')
Somethink like this?
EDIT:
According to your comments below this answer, propably you want something like this, but i am not sure but if not, propably you could change this SQL at your own.
For such non-obvious queries i always use the CTE. I love it because you could use it to 'separate' your logic to simplest 'steps'. Then it's looks simple and easy to see what going on (At least for me) instead of one big query from which it is not so easy to deduce what is happening and is more difficult to edit/read.
First you could use the CTE to get all 'change_slot' type events with dates:
WITH change_slots_dates AS (
SELECT
pe_LogEvent_datetime AS date_start,
pe_LogEvent_datetime + INTERVAL 2 MINUTE AS end_time
FROM pe_LogEvent
WHERE pe_LogEvent_type = 'change_slot'
)
then another CTE to get IDs between this dates (Remember that your's CTE need to be separate by , sign:
rows_to_delete AS (
SELECT
pe.pe_LogEvent_id AS id
FROM pe_LogEvent AS pe
INNER JOIN change_slots_dates AS csd ON (pe.pe_LogEvent_datetime BETWEEN csd.date_start AND csd.end_time)
WHERE pe.pe_LogEvent_type IN ('crash', 'pilot_death', 'eject')
)
after that you can finally delete this entities:
DELETE FROM pe_LogEvent WHERE pe_LogEvent_id IN (SELECT id FROM rows_to_delete);
Notice that this is a one SQL query and you cannot use this as 3 queries. So all seems to be like this:
WITH change_slots_dates AS (
SELECT
pe_LogEvent_datetime AS date_start,
pe_LogEvent_datetime + INTERVAL 2 MINUTE AS end_time
FROM pe_LogEvent
WHERE pe_LogEvent_type = 'change_slot'
),
rows_to_delete AS (
SELECT
pe.pe_LogEvent_id AS id
FROM pe_LogEvent AS pe
INNER JOIN change_slots_dates AS csd ON (pe.pe_LogEvent_datetime BETWEEN csd.date_start AND csd.end_time)
WHERE pe.pe_LogEvent_type IN ('crash', 'pilot_death', 'eject')
)
DELETE FROM pe_LogEvent WHERE pe_LogEvent_id IN (SELECT id FROM rows_to_delete);
I hope it will be finally more helpfull.
Related
Respected all,
I have the following query that is executed only for a date by the filter that is noted, what I need is to run for all the dates in the table, and I can not find the way to indicate that function, I appreciate its special orientation:
update scraper_data_twitter as T1,
(
select Ntweets as Ntweets_var,
(
select COUNT(Ntweets) + 1
from scraper_data_twitter
where (NTweets > Ntweets_var)
and date = '2017-02-13'
) as rank
from scraper_data_twitter
where date = '2017-02-13'
group by SITE,
date
order by NTweets_var desc
) as A
set T1.rnk_Ntweets = A.rank
where T1.ntweets = A.Ntweets_var
I wonder if is possible to create variables inside a sql select query.
Explanation in the following sample, where we select the news from a city published /or updated in the past month (or older):
set #monthBack = 1; -- one month back in time
set #cityName = "Berlin"; -- take a city name
select n.title, coalesce (n.releaseDate, n.updateDate) as news_date
from news as n
inner join with cities as c on c.id = n.cityid
where
c.name = #cityName and
year(coalesce (n.releaseDate, n.updateDate)) =
year(current_date - interval #monthBack month)
month(coalesce (n.releaseDate, n.updateDate)) =
month(current_date - interval #monthBack month)
order by coalesce (n.releaseDate, n.updateDate)
If a publication date is not defined, the news date will be the updated date.
So, I would like to replace the repetition of the coalesce (n.releaseDate, n.updateDate) by a specific variable that is specific to the concrete select statement...
Is it possible in the mysql database?
PS.
As the "problem" is more about sql syntax and code readability, I would like to resolve it just by modifying the sql code, but not applying to external tools or creating additional objects like views or tables (does not worth such complexity for some syntactic optimization)
I can think of many ways to resolve your problems but I'm not sure wich one is the best.
You could do a ";With" subquery to determine the value of "coalesce (n.releaseDate, n.updateDate)" and then use it in the query below.
Or use a stored procedure ou function wich recive the right parameters
You could do a view on your table news and add a column wich is the value of "coalesce (n.releaseDate, n.updateDate)"
Or you can also do something like :
set #monthBack = 1; -- one month back in time
DECLARE #Query NVarchar(Max),
#NewsDate NVARCHAR(MAX)
SET #NewsDate = coalesce (n.releaseDate, n.updateDate) -- Determine the value here
SET #Query =
'select n.title, '+#NewsDate+' as news_date
from news as n
inner join with cities as c on c.id = n.cityid
where
c.name='Berlin' and
year('+#NewsDate+') =
year(current_date - interval #monthBack month)
month('+#NewsDate+')) =
month(current_date - interval #monthBack month)
order by '+#NewsDate
execute sp_executesql #Query
I have a table which logs all "check-ins" into a system. I want to count all "check-ins" from an user for the current day, but there's the problem that sometimes users check-in like two or three times by mistake in one minute. So I just want to count all entries with a gap from at least two minutes
My current command looks like:
"SELECT event_datetime, LEFT(tag_uid,8) AS tag_uid, count(*) as anzahl FROM events WHERE date(event_datetime) = curdate() GROUP BY tag_uid"
So I only want to count it if the gap between event_datetime is at least two minutes grouped by the tag_uid (the user)
Any ideas how to solve that?
first, you need to calculate the gap for each tag_uid and then you can set conditions as you wish. To calculate the gap you need to have a nested select commands which will get the "first checkIn" and "last checkIn" using min and max command. Use the "timediff" to calculate the time gap.
NOTE: i haven't tried the code, also I've added the select commands so you can see the values to find Errors.
the code would look similar to this:
SELECT
tbl_outer_events.event_datetime,
LEFT(tbl_outer_events.tag_uid,8) AS tag_uid,
count(tbl_outer_events.tag_uid) as anzahl,
(select min(event_datetime) from tbl_events as T1 where ( (t1.tag_uid = tbl_outer_events.tag_uid)) and (date(t1.event_datetime) = curdate()) )as `first_checkin`,
(select max(event_datetime) from tbl_events as T1 where ( (t1.tag_uid = tbl_outer_events.tag_uid)) and (date(t1.event_datetime) = curdate()))as `last_checkin`,
(select TIMEDIFF(max(event_datetime), min(event_datetime)) from tbl_events as T1 where ( (t1.tag_uid = tbl_outer_events.tag_uid)) and (date(t1.event_datetime) = curdate())) as `interval`
FROM events as tbl_outer_events
WHERE ((date(event_datetime) = curdate())
AND (select TIMEDIFF(max(event_datetime), min(event_datetime)) from tbl_events as T1 where ( (t1.tag_uid = tbl_outer_events.tag_uid)) and (date(t1.event_datetime) = curdate())) >= '00:20:00')
GROUP BY tag_uid;
PS: please provide us with sample data or desired outcome. it will help us and you to understand the issue.
SET #startdate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=158);
SET #enddate = (select LOG_TIME from log.time where sender='Japan' and receiver ='USA' and code=189);
select * from log.time where DATEDIFF(minute, #startdate, #enddate) >= 10;
Here I want to use 2 variables (#startdate and #enddate) which are populated with multiple entries coming from the select queries used .
And for the last line , I want the select query to return a list of records where the DATEDIFF function is greater than or equal to 10 minutes by using these 2 variables with multiple values .
P.S I am using the Squirrel SQL Client 2.3 )
The issue is I have no idea if it is possible to use multiple values for variables.
Also please advise or provide any solution to the above issue such that the query works in the end.
You can't use variables this way.
Now it's hard to tell for sure not seeing your table schema and sample data but you should be able to do what you want using JOIN with a query like this
SELECT l1.*
FROM log.time l1 JOIN log.time l2
ON l1.sender = l2.sender
AND l1.receiver = l2.receiver
AND l1.code = 158
AND l2.code = 189
WHERE l1.sender = 'Japan'
AND l1.receiver = 'USA'
AND DATEDIFF(minute, l1.log_time, l2.log_time) >= 10
If you were to provide a table schema, sample data and desired output, then it'll be possible to test your query
i have payment table fields
update reason and amount & total field are change negative
UPDATE payment
SET reason = 'refund'
WHERE uid =5 AND date = '2012-05-01' AND accid =2
update single query is it possible?
If I understand you correctly, you also want to set amount column to positive value along with the above statement.
You can use something like this
UPDATE payment
SET reason = 'refund', amount = amount * -1, total = total * -1
WHERE uid =5 AND date = '2012-05-01' AND accid =2
Use ABS(amount) if you wish to always get the positive integer.
SELECT ABS(5);
will output 5
SELECT ABS(-5);
will also output 5
When I looked for the solution, the offered suggestion corrupted my result:
SELECT #TotalAmount:=( SELECT FORMAT(SUM(Amount), 4) FROM MPPayment WHERE PaymentBatchID = 6 and CompanyID=3);
Proper result:
After formatting:
SELECT #TotalAmount:=( SELECT FORMAT(SUM(Amount), 4) FROM MPPayment WHERE PaymentBatchID = 6 and CompanyID=3);
SELECT #TotalAmount * -1;
Probably doesn't work well with formatting.
Another solution is to subtract your digit from zero:
SELECT #TotalAmount:=( SELECT SUM(Amount) FROM MPPayment WHERE PaymentBatchID = 6 and CompanyID=3);
select FORMAT((0 - #TotalAmount), 4 );
To avoid the corruption of the the result I described above, I make formatting at the end of the operation. The result is fine then:
Works also with multiplication by -1:
SELECT #TotalAmount:=( SELECT SUM(Amount) FROM MPPayment WHERE PaymentBatchID = 6 and CompanyID=3);
select FORMAT(( #TotalAmount *-1), 4 );