I found another thread with this similar question but the query wasn't working for me for some reason or another.
I have a table like so:
id | 1 1 5 3 5
I need to use just SQL to echo out the most duplicated number
For instance, that would output:
id | 1 5 3 5
If that makes sense.
How would I achieve this?
Thank you so much
RETURNING JUST UNIQUE ID's
SELECT DISTINCT id FROM myTable
ID |
---------------
1 |
5 |
3 |
See DEMO
RETURNING JUST THE MOST DUPLICATED ID WITH COUNT
SELECT id, COUNT(id) AS Duplicates FROM test
GROUP BY id
ORDER BY Duplicates DESC
LIMIT 1;
ID | Duplicates
---------------
1 | 2
// without the LIMIT clause
ID | Duplicates
---------------
1 | 2
5 | 2
3 | 1
See DEMO
Or, as you see above, there may be TWO ID's that have been duplicated the same amount of times. You could do this, which would return both the highest duplicated ID's, if they're equal:
SELECT id, COUNT(id) AS Duplicates
FROM test
GROUP BY id
HAVING COUNT(id) = (
SELECT COUNT(id) AS great
FROM test
GROUP BY id
ORDER BY great DESC
LIMIT 1
)
ID | Duplicates
---------------
1 | 2
5 | 2
See DEMO
RETURNING JUST UNIQUE ID's IN PURE PHP
$results = // query
$results = array_unique($results);
Use a group by together with a count, like this:
select * from t group by id order by count(id) desc
And add a limit clause in order to get the single most duplicated value:
select * from t group by id order by count(id) desc limit 1
Related
I have a table and I have more than 100 records in the table. I have the same records but the date of added is different.
Table is
m_id | member_id | c_k | b_k | date_of_added
1 | 101 | qwer |sdad1 | 14-02-2019 02:26:30
2 | 101 | qwe2 |sdad2 | 14-02-2019 03:30:20
3 | 102 | qweg |sdad3 | 14-02-2019 04:00:40
4 | 101 | qwe3 |sdad4 | 14-02-2019 04:30:20
5 | 102 | qweg |sdad5 | 14-02-2019 05:45:30
I tried below query but it's displaying all the records related to the member_id=101. I need a last record of the member_id.
SELECT * from m_details WHERE member_id=101 GROUP by member_id ORDER BY date_of_added DESC
My expected output is
m_id | member_id | c_k | b_k | date_of_added
4 | 101 | qwe3 |sdad4 | 14-02-2019 04:30:20
Would you help me out what is wrong with the query?
Tagging PHP team because I am working on PHP but getting the issue in query.
Use this instead :
SELECT * // Gets everything
FROM m_details // From your table
WHERE member_id=101 // For member #101
ORDER BY date_of_added DESC // Gets the last result
LIMIT 1 // Only shows that result
SELECT * from m_details
WHERE member_id=101
ORDER BY date_of_added DESC
LIMIT 1
The GROUP BY is just obscuring the result because it does not necessarily pick the data from the last row it finds.
Your query is correct. You just need to use LIMIT 1, if you need the last record:
SELECT * from m_details WHERE member_id=101 GROUP by member_id ORDER BY date_of_added DESC LIMIT 1;
SELECT * from m_details WHERE member_id=101 ORDER BY m_id DESC LIMIT 1
Using the above query for expected output. In this case, does not need to group by clause.
In MySQL 8.0, use ROW_NUMBER() :
SELECT * FROM (
SELECT t.*, ROW_NUMBER() OVER(PARTITION BY member_id ORDER BY date_of_added DESC) rn
FROM mytable t
) WHERE member_id=101 AND rn = 1
The advantage of this approach is that it will work even if you need to display the information for more than on logic, as opposite to the GROUP BY/LIMIT solution, that only works for a single user at a time.
In earlier versions of MySQL, this can also be implemented using a NOT EXISTS condition :
SELECT t.*
FROM mytable t
WHERE
t.member_id = 101
AND NOT EXISTS (
SELECT 1
FROM mytable t1
WHERE t1.member_id = t.member_id AND t1.date_of_added > t.date_of_added
)
As you want to get the only one latest record, use DESC and LIMIT = 1 as below:
SELECT * from m_details WHERE member_id = 101 ORDER BY date_of_added DESC LIMIT 1;
As member_id can have duplicate value(according to your given dataset), you can identify m_id column as unique and (auto) increasing value(it seems so) and sort based on that column in descending order to get the updated value and then just pick the first row by setting LIMIT 1. So write your query removing group by clause:
SELECT * from m_details WHERE member_id=101 order by m_id DESC LIMIT 1;
Hope, this will help.
N.B.: It seems that new entries can't have lower date_of_added value than previous as there is no specific info about that, otherwise sort by date_of_added
I have a huge number of rows that I'd like to get say, last 5 records inserted in that database from 10 different users. If the same user inserted the last 3 rows into database, we must get one row, skip the others two and move to get a row per user, until it count up to 5.
A database like that:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
1 | 4 | baa
4 | 5 | baa0
5 | 6 | baa1
5 | 7 | baa2
6 | 8 | baa3
7 | 9 | baa4
Should return:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
4 | 5 | baa0
5 | 6 | baa1
The current filter was done by PHP, like this:
$used = array();
while ($data = mysql_fetch_array($query)) {
$uid = $data['user_id'];
if(in_array($uid, $used))
continue;
array_push($used, $uid);
// do something with data
}
But I want to refactor it, and do the filter purely by mysql, if possible. I don't know much MySql and that's why I'm having problem to archive this...
Here's what I've tried
select DISTINCT(user_id), news_id, title from XXX
WHERE GROUP BY (news_id) DESC
LIMIT 0,5
How can I do that?
1 way you can do it is to generate a partitioned row number per user and then select 5 records where RowNumber = 1.
SELECT *
FROM
(
SELECT
d.user_id
,d.news_id
,d.title
,(#rn:= if(#uid = user_id, #rn + 1,
if(#uid:=user_id,1,1)
)
) as RowNumber
FROM
Data d
CROSS JOIN (SELECT #uid:=-1, #rn:=0) vars
ORDER BY
user_id
,news_id
) t
WHERE
t.RowNumber = 1
ORDER BY news_id
LIMIT 5;
http://rextester.com/JRIZI7402 - example to show it working
Note you can change the row order by simply changing the ORDER BY statement of the derived table so if you have a column that will signify the latest record e.g. an identity column or a datetime column you can use that, but user_id must be the first criteria to be partitioned correctly.
Do it from your query.
"SELECT * FROM table GROUP BY user_id ORDER BY news_id DESC LIMIT 5"
well, i think this will achieve what you are after.
select user_id, news_id, title from tableName
GROUP BY user_id
ORDER BY news_id DESC
LIMIT 0,5
Hope this helps!
I have a many-to-many table with approximately this structure:
id | obj
----+---------
1 | 27
1 | 42
2 | 32
2 | 42
2 | 162
2 | 89
3 | 2
3 | 209
Essentially the table associates any number of objects (obj) with any number of collections (id).
I am trying to SELECT from this table in a way that will return the number of rows in a GROUP BY clause grouping by id, and also the number of grouped rows grouped by the number of rows in each group.
If I simply do SELECT COUNT(id) FROM table GROUP BY id, I naturally get the following:
id | COUNT(id)
----+---------
1 | 2
2 | 4
3 | 2
That is, there is one row where COUNT(id) = 4 and there are two rows where COUNT(id) = 2. So far so good. But not what I’m looking for here.
What I need is this: for each distinct value returned by COUNT(id) (2 and 4 in this case), select both COUNT(id) and the number of rows that match that value in their COUNT(id) column (in this case 2 and 1, respectively: 2 rows have COUNT(id) = 2 and 1 row has COUNT(id) = 4).
In other words, from the table above, I would want this:
id_cnt | grp_cnt
-------+---------
2 | 2
4 | 1
– since grouping the table by id, you get two rows where COUNT(id) is 2 (ids 1 and 3); and one row where COUNT(id) is 4 (id 2).
Wrack my brain as I may, though, I cannot figure out a way to do this in one single query.
The closest I’ve been able to get to something that made sense in my head was this:
SELECT COUNT(*), id_cnt FROM table JOIN (SELECT COUNT(id) id_cnt FROM table GROUP BY id) a
– but that gives:
count(*) | id_cnt
---------+---------
21100 | 2
– which I admit confuses me a bit.
Can it be done?
(I find it odd that I can’t find this question already asked—surely this must have been asked before? Perhaps I’m just wording my search queries poorly…)
You can add another level of grouping around your first grouped query.
SELECT id_cnt, COUNT(*) AS grp_cnt
FROM (
SELECT COUNT(*) AS id_cnt
FROM test.test GROUP BY id) id_cnts
GROUP BY id_cnt;
You can get the cont by id this way
select id, count(*) as ctn
from table
group by id
and the count of same count with a second level count
select ctn, count(*)
from ( select id, count(*) as ctn
from table
group by id) t
group by ctn
I have this table: I want to search by UID
ID | VID | UID
1 | 1 | 5
1 | 1 | 6
1 | 2 | 6
2 | 3 | 5
2 | 3 | 6
2 | 4 | 6
I want to end up with this result:
ID | VID | UID
1 | 2 | 6
2 | 4 | 6
In other words, only select the entries where the VID is MAX of the UID but keeping in min NID could differ. Something like this I suppose:
select * from TABLE where uid = 6 and max(vid)
???
But this doesn't work?
One way is to order by the value in descending order (so the max is at the top), then just select the first result.
SELECT t.ID,
t.VID,
t.UID
FROM table t
WHERE t.ID = 1
ORDER BY t.VID DESC
LIMIT 1
Or do you mean you want all rows where t.VID is the highest value? In which case you could do something like this,
SELECT t.ID,
t.VID,
t.UID
FROM table t
WHERE t.ID = 1
AND t.VID = (SELECT MAX(VID) FROM table);
EDIT: Based on the edit to your question, it looks like you just want the max VID value for each ID? If I'm understanding you correctly, then this should give you what you need.
SELECT t.ID,
max(t.VID) as VID,
t.UID
FROM table t
WHERE t.UID = 6
GROUP BY t.ID
You need to have a subquery. This should work:
select * from TABLE where ID='1' AND VID=(select max(VID) from TABLE)
I expect your real-life example is more complicated (at least has more data).
This query will give you the row you want.
SELECT id,vid, uid
FROM TABLE
where id = 1
and vid in (select max(vid) from TABLE where id = 1)
I have another Problem
I just can show you this on an example:
I got a Table called "myTable" with 7 entries
myTable | id | user_id |
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 2
9 2
10 2
Now i want to list just 3 entries of any user_id, but i cant find out myself how to.
Please help!
------- EDIT
My result have to look like this:
id=1 | user_id=1
id=2 | user_id=1
id=3 | user_id=1
id=5 | user_id=2
id=6 | user_id=2
id=7 | user_id=2
select * from table as t1
where (select count(*) from table as t2
where t1.user_id = t2.user_id and t2.id < t1.id) <3
SELECT *
FROM table
ORDER BY ...
LIMIT 3
The LIMIT clause takes two arguments: number of rows to return, and an offset if you want to display something other than the first X rows. Details here in the MySQL docs.
If you want only 3 rows, you can use limit :
select * from myTable limit 3;
SELECT * FROM table LIMIT 3
http://dev.mysql.com/doc/refman/5.0/en/select.html