Example, Lets suppose I have a table like next one:
id | start | userId
1 3 1
2 2 2
3 5 1
Now, I want to get all the row information for the second higher value of the column start related to some userId. So, if userId equals to 1 I'm expecting to get the next result:
(id, start, userId) = (1,3,1)
I have tried this query:
SELECT id, max(start) FROM table_user WHERE userId = 1;
But this gives me the higher number.
You can do this easy using ordering by column start and the features of LIMIT, like this:
SELECT
*
FROM
table_user
WHERE
userId = 1
ORDER BY
`start` DESC LIMIT 1, 1
You can check this online also: DB-Fiddle
Related
I have a table called deals, it has records like this for example
id deal_ref objectname status
1 1234 tom correct
2 1234 tom correct
3 1234 jerry wrong
4 1234 tom correct
I need to identify all latest deals where the status is "correct for example, but the last entry(row 4) must meet the following criteria, where the Max ID is equal to the deal_ref and the status is correct
I tried this
select distinct deal_ref, deal_status
from dealv1 d
where d.deal_ref = max(id)
and d.deal_status = 'Prospect'
and date_created between '2022-11-02 00:00:00' and '2022-11-04 00:00:00'
You use other names in your SQL than in the table (deal_status, date_created).
Nevertheless try do it the following:
SELECT *
FROM dealv1 d
WHERE status = 'correct'
ORDER BY ID DESC
LIMIT 1
i donĀ“t get exactly what you are trying to do with the maxID. You just want the one row where deal_ref=max(id) and status is correct?
Then add
AND deal_ref = (SELECT MAX(id) from dealv1)
after 'correct' from the above statement.
Guys the query below worked, but its displaying multiple deal_refs that has the same deal_ref, for example 2 rows below each other with deal_ref 1234 twice.
SELECT *
FROM dealv1 d
WHERE status = 'correct'
ORDER BY ID DESC
LIMIT 1
Is it possible to get only 1 row after ordering? I don't want to load DB so much, so I want to get only 1 row (it may be from the middle), here is an example:
ID
User
Points
1
user1
10
2
user2
60
3
user3
45
I want to get the fe. the second user after ORDER BY `points` DESC, so the table will look like
ID
User
Points
2
user2
60
3
user3
45
1
user1
10
The second user is user3, and I want to return just that one row. It is possible? Or do I need to get all and just LIMIT it?
If you are using MySql 8+ you can use rank, for example:
with r as (
select * , Rank() over(order by points desc) rnk
from t
)
select id, user, points
from r
where rnk = 2;
If you want to strictly get only one row, corresponding to the second highest points, then my guess is that on ties you want the lowest id. In that case you can use the LIMIT function accordingly.
SELECT *
FROM tab
ORDER BY points DESC,
ID
LIMIT 1,1
The so written LIMIT clause will allow you to start limiting from the second row, then takes the first row available (which is the second one).
Check the demo here.
I have one table called quiz_data which have column called id, user_id and user_band which have value like below
id user_id user_band
1 1 A
2 2 B
3 1 A
4 3 A
I want get total unique user_band with keep in mind user_id will count only one time. from above example I want result called userband A = 2 and B = 1.
I have tried like below
select('user_band,COUNT(distinct(user_id)) as count')from quiz_data GROUP BY user_band ORDER BY user_band
but its not working properly. Let me know if someone can help me for same.
Thanks!
The syntax you want is:
select user_band, count(distinct user_id) no_users
from quiz_data
group by user_band
order by user_band
I have following table:
id systemid value
1 1 0
2 1 1
3 1 3
4 1 4
6 1 9
8 1 10
9 1 11
10 1 12
Now here i have 8 records of systemid = 1 so now i want to keep only latest 3 records (desc order) and delete older records whose systemid=1
I want output like :
id systemid value
8 1 10
9 1 11
10 1 12
I just want to delete old records of systemid=1 only if its count > 5 and keep its latest 3 records.
How can i do this in query ?
If you do not always have 8 records and want to select the last 3 records from the table where systemid=1 however many records there are, then a good way to do this is to use the IN selector in your SQL statement.
It would be good is you could do this simply using the statement
SELECT * FROM mytable WHERE id IN (SELECT id FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3)
However this is not yet supported in MySQL and if you try this then you will get an error like
...doesn't yet support 'LIMIT & IN/ALL/SOME subquery'
So you need a workaround as follows (using SELECT to test):
SET #myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
SELECT * FROM mytable WHERE FIND_IN_SET(id,#myvar);
The way that this works (first line) is to set a variable called #myvar which will hold the last 3 values as a comma separated string if id values. In your case
9,8,10
Then select the rows where the 'id' is in this string.
Replace the 'SELECT *' with 'DELETE FROM' to finalize the result so your query will be
SET #myvar := (SELECT GROUP_CONCAT(id SEPARATOR ',') AS myval FROM (SELECT * FROM `mytable` WHERE systemid=1 ORDER BY id DESC LIMIT 3 ) A GROUP BY A.systemid);
DELETE FROM mytable WHERE NOT FIND_IN_SET(id,#myvar);
I hope that this helps.
Try this to keep the latest three records that have system_id equal to 1 and count is greater than 5:
DELETE FROM <table_name> WHERE system_id = 1 AND value > 5 ORDER BY id DESC LIMIT 3
You can specify an offset with the LIMIT keyword in your query so the newest 5 rows are kept. According to MySQL's documentation, however, there's no easy way to limit from an offset all the way to the last; instead, they suggest this:
To retrieve all rows from a certain offset up to the end of the result set, you can use some large number for the second parameter.
So this SQL should do the trick:
DELETE FROM table where systemid = 1 ORDER BY value DESC LIMIT 5,45484848
This is going to be a very long query. What you need is for every system_id that have more than 5 records you want to delete the record that are less than ranking 3.
I'm going to seperate the queries and use names for them at the end.
1_ ranking_query: abriviation is RQ
In mysql there is no rownum or something like that hope this query return the records ranked from ghe first to the last.
SELECT
#rank := #rank + 1 as rank,
id,
system_id,
value
FROM table_name, (select #rank:=0) as rt
order by system_id, value desc
this will rank every record in your table and the main benefit is the record with the same system_id will be after each other in desc order
system_id value rank
1. 10. 1
1. 9. 2
1. 7. 3
1. 5. 4
1. 3. 5
1. 2. 6
2. 12. 7
2. 10. 8
3. 11. 9
........
......
3. 1. 15
In this example for system_id 1 we need to keep only the three first (1,2,3) record same thing for system_id 3 (9,10,11)
2_ filter_query. Abriviation is: FQ
Because you want to delete based on count 5 we need this extra query
SELECT
system_id
FROM table_name
GROUP BY system_id
having count(*) > 5
result:
system_id
1
3
4_ third_query abriviation: RQD
a query to know which rank should we start do delete from for every system_id in mysql we need to rewrite the first query again but here i'm going to use Abriviation to keep the answer short.
SELECT
system_id,
min_rank + 3 from_rank
FROM (
SELECT
RQ2.system_id,
min(RQ2.rank) as min_rank
FROM (rank_query) RQ2
GROUP BY system_id) RS
so for the same example the we going to have this result
system_id. from_rank
1. 4
2. 9 -- this record will be removed by the filter_query
3. 12
FINAL QUERY:
so we need to delete record that exist in filter query and the ranking is bigger than from_rank.
DELETE FROM table_name WHERE
id in (
SELECT
RQ.id
FROM
rank_query RQ INNER JOIN filter_query FQ ON rq.system_id = FQ.system_id
INNER JOIN third_query RQD ON RQ.rank >= RQD.from_rank)
I hope this idea work sorry for any syntax error i used my phone to answer i like this kind of query
I have a table in mySql. I need to find how much entry in table which have entered only one time and another records which are enter for second time. please see the screenshot. count is based on shg_id.
if I correctly understand, you need this:
select entered, count(*) from (
select shg_id, count(*) as entered
FROM mytable
group by shg_id
having count(*) between 1 and 2
)t
group by entered
The following should do if it has an id attribute:
SELECT * FROM Table
HAVING COUNT(shg_id) = 1 -- Record equal to 1
Or
SELECT * FROM Table
HAVING COUNT(shg_id) = 2 -- Record equal to 2
Updated - This works well on my side:
SELECT COUNT(shg_id) AS Total
FROM Table
WHERE shg_id= 4
GROUP BY shg_idHAVING COUNT(shg_id) = 1
Another one - Slightly taken from OTARIKI:
SELECT shg_id, COUNT(*) AS Total FROM Table
GROUP BY shg_id
HAVING COUNT(shg_id) BETWEEN 1 and 2