Another distinct and limit mysql - mysql

The following does what it supposed to
it returns 200+ distinct records w/o the "limit 2"
What I want is to return 2 distinct records, but it stops after the 1st 2 records, meaning I only get 2 records
select distinct LEFT(`name`, LOCATE("(", `name`)-1), user_id, id
from ppbv79_listings
where user_id = 3798 and category_id = 30
group by LEFT(`name`, LOCATE("(", `name`)-1)
limit 2
Name user_id id
Germany 1213 Used Carl Sonnenschein 3798 2160555
Germany 1213 Used Carl Sonnenschein 3798 2160556

Try this:
select A.`trimmedName`, A.user_id, A.id
from
(select LEFT(`name`, LOCATE("(", `name`)-1)
`trimmedName`, user_id, id,count(category_id) `count`
from ppbv79_listings
where user_id = 3798 and category_id = 30
group by LEFT(`name`, LOCATE("(", `name`)-1), user_id, id
order by `count` desc) A
limit 2;
I assume there are some repetitions you would want to removed, and fetch the just the top 2 rows of data that repeats most.

Related

Get the next max(id)

I've got the following table:
booking_id
user_id
11
1
12
76
13
932
14
1
15
626
16
1
17
3232
I want to access the 2nd maximum booking_id for user 1.
The expected result is user_id = 1, booking_id = 14.
I've been working over these hellish flames for way too long, this doesn't do any good:
select booking.user_id, b1.booking_id from booking
left join(select
user_id,
booking_id
from booking
where booking_id = (select
max(booking_id)
from booking
where booking_id <> (select
max(booking_id)
from booking))
group by user_id)
as b1 on b1.user_id = booking.user_id
where booking.user_id = '1'
Please note I've managed to do it as a calculated column but that's useless, I need the derived table.
If you are using MySQL, you can avoid the (rather messy) double sub-query by using LIMIT & OFFSET
Just add order by booking_id desc LIMIT 1 OFFSET 1 and you will get the second highest booking_id. For example ...
select * from booking where user_id = 1 order by booking_id desc OFFSET 1 LIMIT 1
I tested this on one of my tables & it worked fine. If you have an index on booking_id it should be really fast.
If you want the second highest booking for the user who holds the highest booking, then this should work
SELECT * FROM booking
WHERE user_id in
(select user_id from booking order by booking_id desc limit 1)
ORDER BY booking_id DESC LIMIT 1 OFFSET 1
The sub-query finds the user_id of the user with the highest booking, then the main query finds their second highest booking
A simple way to do it is using LIMIT OFFSET:
SELECT *
FROM booking
WHERE user_id = 1
ORDER BY booking_id DESC
LIMIT 1 OFFSET 1
Demo here
By using the answer in this question What is the simplest SQL Query to find the second largest value? https://stackoverflow.com/a/7362165/14491685
you can integrate with your query to get it like this:
select * from booking
where booking_id =
(select max(booking_id) from booking
where user_id =1
and booking_id not in (SELECT MAX(booking_id ) FROM booking ))

Sorted data in groups

Dataset:
id uid activity postid
1 20 A 1
2 20 A 1
3 6 A 1
4 3 A 1
5 6 A 1
6 13 A 1
7 13 B 1
8 18 B 1
9 18 B 1
10 1 A 1
Current Results:
id uid uid_list groupCount activity postid
9 18 18,13 3 B 1
1 20 1,13,6,3,20 7 A 1
Expected Results:
id uid uid_list groupCount activity postid
9 18 18,13 3 B 1
10 1 1,13,6,3,20 7 A 1
The query I have:
SELECT
id,
uid,
GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
COUNT(*) as groupCount,
activity,
postid
FROM (
SELECT *
FROM `user_activities`
ORDER BY id DESC) as tbl
GROUP BY
activity, postid
ORDER BY
id DESC
I want to group by activity and postid while having the result in descending order by id. And want to have the latest id and uid for every group. I don't understand why this query doesn't return the expected output.
From what I understand id value is increasing. To get the latest values you could use an aggregate function MAX().
Also, your inner query with ordering is unnecessary because the engine has to sort the resultset by id anyways when building result for GROUP_CONCAT().
To retrieve uid for a particular id column you need to self join to the same table.
SELECT
a.id, b.uid, a.uid_list, a.groupcount, a.activity, a.postid
FROM (
SELECT
MAX(id) as id,
GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
COUNT(*) as groupCount,
activity,
postid
FROM user_activities a
GROUP BY
activity, postid
) a
INNER JOIN user_activities b ON a.id = b.id
Probably the simplest method is the group_concat()/substring_index() trick:
SELECT MAX(ID) as id,
SUBSTRING_INDEX(GROUP_CONCAT(uid ORDER BY ID DESC), ',', 1) as uid,
GROUP_CONCAT(DISTINCT uid ORDER BY id DESC) as uid_list,
COUNT(*) as groupCount,
activity, postid
FROM user_activities ua
GROUP BY activity, postid
ORDER BY id DESC;
There are some limitations to this approach, in the sense that GROUP_CONCAT() has a maximum length for the intermediate value. Typically the default is sufficient, but you might need to change that value if many, many rows match each group (and you already have this issue for the list of uids anyway).

MySQL select top ten records with no duplicate uid

I have the following table (user_record) with millions of rows like this:
no uid s
================
1 a 999
2 b 899
3 c 1234
4 a 1322
5 b 933
-----------------
The uid can be duplicate .What I need is to show the top ten records(need inclued uid and s) with no duplicate uid order by s (desc). I can do this by two steps in the following SQL statements:
SELECT distinct(uid) FROM user_record ORDER BY s DESC LIMIT 10
SELECT uid,s FROM user_record WHERE uid IN(Just Results)
I just wana know is there a bit more efficient way in one statement?
Any help is greatly appreciated.
ps:I also have following the SQL statement:
select * from(select uid,s from user_record order by s desc) as tb group by tb.uid order by tb.s desc limit 10
but it's slow
The simpliest would be by using MAX() to get the highest s for every uid and sorted it based on the highest s.
SELECT uid, MAX(s) max_s
FROM TableName
GROUP BY uid
ORDER BY max_s DESC
LIMIT 10
SQLFiddle Demo
The disadvantage of the query above is that it doesn't handles duplicates if for instance there are multiple uid that have the same s and turn out to be the highest value. If you want to get the highest value s with duplicate, you can do by calculating it on the subquery and joining the result on the original table.
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT DISTINCT s
FROM TableName
ORDER BY s DESC
LIMIT 10
) b ON a.s = b.s
ORDER BY s DESC

Order by top five repeated IDs

There is a table in my database duplicate_id which contains multiple ids and also contains many duplicate ids in it. What I have been trying to do is to sort top five ids which are being repeated the most in the table duplicate_id. Kindly let me know how can i do that
Table Structure: ID | Message
Expected output:
ID | Number of repeats
201 8
212 7
205 5
209 3
229 2
SELECT ID, COUNT(*) AS `Number of repeats`
FROM duplicate_id
GROUP BY ID
ORDER BY COUNT(*) DESC
LIMIT 5
Try the order by so sort your results:
Select * from table order by repeats desc limit 5
well... try this (I don't know mysql, so I have to guess)
select ID,
count(*) as 'Number of Repeats'
from duplicate_ID
group by ID
order by 2
Another approach would be
select ID, 'Number of Repeats'
from (
select ID,
count(*) as 'Number of Repeats'
from duplicate_ID
group by ID
) x
order by 'Number of Repeats'

mysql count unique row values

TABLE quotation
id clientid
1 25
2 25
3 25
4 25
5 26
How can I query how many different clients exist in TABLE quotation? I don't want duplicate entries to be counted more than once.
I need the answer to be 2, in 1 row, because the only non-duplicated entries are (25, 26).
select count(distinct clientid) from quotation
read more
I find a way out
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY
clientid) t1
If you want to count the total number of unique entries this will return a number in column count.
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY clientid having count(*) > 1) t1
If you want to count the total number of entries with duplicate rows then use the following mysql.
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY clientid having count(*) >= 2) t1
I tried the following on a MySQL 5.x database.
id is an integer and clientid is an integer. I populated with two rows:
id clientid
1 25
2 25
This SQL query will print the rows that have exactly 2 elements:
select * from test1 group by clientid having count(*) = 2;
If you want 2 or more elements, replace = 2 in the example above with >= 2.
select * from test1 group by clientid having count(*) >= 2;
SELECT clientid, COUNT(clientid) FROM quotation
GROUP BY clientid