Trying to delete the records if greater then 25? - mysql

I am trying to delete all records so I only have the last 25 records. I am trying to figure this out but I can't seem to figure out, my MySQL version doesn't support the DELETE LIMIT OFFSET that most suggest, so I am trying to do
DELETE FROM
account_versions
WHERE
account_versions_id < (
SELECT
account_versions_id
FROM
account_versions
ORDER BY
account_versions_id
DESC
LIMIT 24, 1)
AND
account_id = 1
But I can't seem to get it to work. I want to only have the last 25 records for account_id = 1

So, as you said that account_versions_id is an autoincrement. Here is what you need:
DELETE FROM account_versions
WHERE account_id = 1
and account_versions_id IN
(select account_versions_id
from
(SELECT account_versions_id, #id:=#id+1 as rn
FROM account_versions,
( select #id:=0 ) a
ORDER BY account_versions_id DESC) x
where rn > 25)
Now it should work.

Related

How to check if id occurs in other table in MySQL

I have a table an_visit that has column visit_id. There is also a table an_transaction that has some visit_id too.
I would like to get a new column in MySQL based on if visit_id occurs in both tables. My approach:
SELECT visit_id, datetime_add, ISNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id), 0)
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50
But I got this error: MySQLdb.OperationalError: (1582, "Incorrect parameter count in the call to native function 'ISNULL'"). What do I do wrong, please?
SELECT visit_id, datetime_add, ISNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id limit 1))
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50
OR
SELECT visit_id, datetime_add, IFNULL((SELECT
1
FROM an_transaction
WHERE an_transaction.visit_id = an_visit.visit_id limit 1),0)
FROM an_visit
WHERE datetime_add >= '2021-08-01'
LIMIT 50

Deleting rows using a limit and offset without using IN clause

I want to delete rows with an offset, so I am forced to use a nested query since its not support in the raw DELETE clause.
I know this would worked (ID is the primary key):
DELETE FROM customers
WHERE ID IN (
SELECT ID
FROM customers
WHERE register_date > '2012-01-01'
ORDER BY register_date ASC
LIMIT 5, 10
);
However, this is unsupported in my version as I get the error
This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'.
Server version: 10.4.22-MariaDB
What can I do to achieve the same result as above that is supported in my version.
CREATE TABLE customers (
ID INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32) NOT NULL,
REGISTER_DATE DATETIME NOT NULL
);
Join the table to a subquery that uses ROW_NUMBER() window function to sort the rows and filter the rows that you want to be deleted:
DELETE c
FROM customers c
INNER JOIN (
SELECT *, ROW_NUMBER() OVER (ORDER BY register_date) rn
FROM customers
WHERE register_date > '2012-01-01'
) t ON t.ID = c.ID
WHERE t.rn > 5 AND t.rn <= 15; -- get 10 rows with row numbers 6 - 15
See the demo.
If I did not miss something a simple delete with join will do the job...
delete customers
from (select *
from customers
WHERE register_date > '2012-01-01'
order by register_date asc
limit 5, 2) customers2
join customers on customers.id = customers2.id
Here is a demo for your version of MariaDB
You could try assigning a rank to your rows with the ROW_NUMBER window function, then catch those rows whose rank position is between 5 and 15.
DELETE FROM customers
WHERE ID IN (
SELECT *
FROM (SELECT ID,
ROW_NUMBER() OVER(
ORDER BY IF(register_date>'2012-01-01', 0, 1)
register_date ) AS rn
FROM customers) ranked_ids
WHERE rn > 4
AND rn < 16
);
This would safely avoid the use of LIMIT, though achieves the same result.
EDIT. Doing it with a join.
DELETE FROM customers c
INNER JOIN (SELECT ID,
ROW_NUMBER() OVER(
ORDER BY IF(register_date>'2012-01-01', 0, 1)
register_date ) AS rn
FROM customers) ranked_ids
WHERE
) ids_to_delete
ON c.ID = ids_to_delete.ID
AND ids_to_delete.rn > 4
AND ids_to_delete.rn < 16

How to get Last and Secondlast Record from mysql table

From the above image i have n number of records with cat_id and sub_cat_id but in image only two are there.
so i want get the last and secondlast score_in_per value as named lastScore and latetsScore..
how can i retrieve that..?
SELECT
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 2,0) as lastScore,
(SELECT score_in_per FROM tbl_student_skill_score ORDER BY date DESC LIMIT 1) as latetsScore
i am new to this complicated mysql logics..This what i have tried..
Example:
lets say one user email is inststudent#yopmail.com take the same test 2 times and the test is linked up with one category and sub category.
so the user will take the test any number of times...
from that records i want to get the last two records percentage.
If I understand you correctly; you want to select the two most recent results of a specific type of test taken by a specific student.
You don't use the LIMIT clause correctly. This is the correct syntax: LIMIT {[offset,] row_count | row_count OFFSET offset}. Also, you completely left out the where clause.
So the query should be:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY date DESC LIMIT 1
)AS latetsScore;
If a student can take the test multiple times a day (like your image suggests) than you should also order by id (supposing that the id is always greater for newer results) or better still, only by the id:
SELECT
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1, 1
)AS lastScore,
(SELECT score_in_per FROM tbl_student_skill_score
WHERE user_email = "email of the user you are interested in"
AND cat_id = categoryOfTestOfInterest
AND sub_cat_id = subcategoryOfTestOfInterest
ORDER BY id DESC LIMIT 1
)AS latetsScore;
One of the way of solving this problem is by using Partition By .
Step1: I have ranked the data for distinct cat_id and sub_cat_id in descending order of date by partition by.
Step2: I have used rank1 which is the latest score and merged it with rank2 which is the second last score
with chck as
(select
cat_id,sub_cat_id,score_in_per,date1,
row_number() over(partition by cat_id,sub_cat_id order by
cat_id,sub_cat_id,date1 desc) as row_num
from tbl)
select a.*,b.second_last_score from
(select cat_id,sub_cat_id,score_in_per,date1,row_num as last_score from chck where row_num=1) a
left join
(select cat_id,sub_cat_id,score_in_per,date1,row_num as second_last_score from chck where row_num=2) b
on a.cat_id = b.cat_id and a.sub_cat_id = b.sub_cat_id;
Let me know in case of any query.
SELECT
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1 ) AS latestScore,
( SELECT score_in_per FROM tbl_student_skill_score WHERE cat_id=1 and sub_cat_id=5 ORDER BY date,id DESC LIMIT 1,1 ) AS lastScore

How to write sql query to get items from range

I would like to get values without the smallest and the biggest ones, so without entry with 2 and 29 in column NumberOfRepeating.
My query is:
SELECT Note, COUNT(*) as 'NumberOfRepeating'
WHERE COUNT(*) <> MAX(COUNT(*))AND COUNT(*) <> MIN(COUNT(*))
FROM Note GROUP BY Note;
SELECT Note, COUNT(*) as 'NumberOfRepeating'
FROM Notes
GROUP BY Note
HAVING count(*) <
(
SELECT max(t.maxi)
FROM (select
Note, COUNT(Note) maxi FROM Notes
GROUP BY Note
) as t
)
AND
count(*) >
(
SELECT min(t.min)
FROM (select
Note, COUNT(Note) min FROM Notes
GROUP BY Note
) as t
)
try this code.
One method would use order by and limit, twice:
select t.*
from (select t.*
from t
order by NumberOfRepeating asc
limit 99999999 offset 1
) t
order by NumberOfRepeating desc
limit 99999999 offset 1;
Try this code,
Select * from Note where NumberOfRepeating < (select MAX(NumberOfRepeating) from Note ) AND NumberOfRepeating > (select MIN(NumberOfRepeating) from Note );
Here in the code, as in your table Note is the name of the table, and NumberOfRepeating is the column name, as in your table.
Try this. It should work
SELECT *
FROM ( SELECT Note, COUNT(*) as 'NumberOfRepeating'
FROM Notes
GROUP BY Note
ORDER BY NumberOfRepeating DESC
LIMIT 1, 2147483647
) T1
ORDER BY T1.NumberOfRepeating
LIMIT 1, 2147483647

How to insert same data in 1 table and Limit it by 10

I am working in a "Recently view by user" script. I have 3 tables, tbl_user, tbl_articles and tbl_recently_viewed. My tbl_recently_viewed has 3 fields, user_id(from tbl_user),article_id(from tbl_articles) and date, and i made 2 primary keys, user_id and article_id. My problem is i want to limit a certain user_id to be inserted in tbl_recently_viewed by 10. Is there a way i can do this?
Thanks.
To delete the oldest item for a user from tbl_recently_viewed:
DELETE v.* FROM tbl_recently_viewed v
JOIN (SELECT MIN(date) mindate
FROM tbl_recently_viewed
WHERE user_id = ?) r
ON v.date = r.mindate
WHERE user_id = ?
I think that you need a trigger to do what you want to do. If you are only inserting rows, then you can use an insert trigger to remove the oldest.
The following is intended just as an example:
CREATE TRIGGER t_keep10 after INSERT ON t
FOR EACH ROW BEGIN
if (10 > (select count(*) from t where t.user_id = new.user_id)) then
delete from t where t.article_id = (select a from (select article_id as a from t t2 where t2.user_id = t.user_id order by date desc limit 1))
end if;
END;
|
You could delete rows after 10 with this query:
delete from tbl_recently_viewed where user_id=1 and date <= (select max(date) from (select date from tbl_recently_viewed where user_id=1 order by date desc limit 10,999) as tmp);
or just delete oldest row with query:
delete from tbl_recently_viewed where user_id=1 order by date limit 1;