I have the following table called user_pin_tags with the following data that I need to query and show distinct tags and a count of each:
| user_id | pin_id | tag_id |
+---------+--------+--------+
1 | 34 | 7
2 | 34 | 7
3 | 34 | 15
4 | 34 | 16
5 | 34 | 16
6 | 34 | 16
Right now I am using the following query to get the distinct tag_ids
SELECT DISTINCT tag_id
FROM user_pin_tags
WHERE pin_id = 34
which gives the result of:
| tag_id |
+--------+
7
15
16
I need to modify this query to give the distinct tag_ids as well as the count within that pin_id, so I want to generate this result set:
| tag_id | count |
+--------+-------+
7 | 2
15 | 1
16 | 3
How can I modify this query to achieve this?
Use COUNT(*) and GROUP BY:
SELECT tag_id, COUNT(*) AS total
FROM user_pin_tags
WHERE pin_id = 34
GROUP BY tag_id
SELECT
DISTINCT(tag_id)
,count(pin_id)
FROM user_pin_tags
WHERE pin_id = 34
GROUP BY tag_id
Group By should do it ... i think.
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
You can group by the tag_id:
SELECT tag_id, COUNT(pin_id)
FROM user_pin_tags
WHERE pin_id = 34
GROUP BY tag_id
Related
I have this table (with 100k+ rows):
room_id | emote_id | count | since
----------------------------------------
1 | 22 | 718| 1577135778
1 | 23 | 124| 1577135178
1 | 24 | 842| 1577135641
2 | 22 | 124| 1577135748
2 | 23 | 345| 1577136441
2 | 24 | 43| 1577543578
3 | 22 | 94| 1572135778
3 | 23 | 4718| 1577135641
3 | 24 | 18| 1577134661
4 | 22 | 78| 1577125641
4 | 23 | 128| 1577135778
4 | 24 | 278| 1577132577
I want to get for each emote_id the row where count is the highest for this emote_id
So for this example I'd like to get this as response:
room_id | emote_id | count | since
----------------------------------------
1 | 22 | 718| 1577135778
3 | 23 | 4718| 1577135641
1 | 24 | 842| 1577135641
I'm stuck at building the query and need help. :(
You can use nested subquery with max() aggregation
select t1.*
from tab t1
join (select emote_id, max(count) as count
from tab
group by emote_id ) t2
on t1.emote_id = t2.emote_id
and t1.count = t2.count
for db version 8+ you can use window analytic functions such as dense_rank():
select room_id, emote_id, count, since
from
(
select t.*, dense_rank() over (partition by emote_id order by count desc) as dr
from tab t
) tt
where tt.dr = 1
Demo
All matching maximum values for count return through use of dense_rank() in case of tie( having equal valued count for any of emote_id ). If analytic function was row_number(), then only one row would return even if tie occurs.
I hope someone can help with my sql query.
I got a table looking like this:
ID | post_id | likes | somemorestuff...
1 | 1000 | 5 | ...
2 | 1000 | 20 | ...
3 | 1001 | 7 | ...
4 | 1002 | 11 | ...
5 | 1003 | 19 | ...
6 | 1003 | 19 | ...
7 | 1003 | 18 | ...
8 | 1004 | 17 | ...
9 | 1005 | 6 | ...
Now i need to filter them to MAX likes and distinct post id.
I found this code but its not working 100% in my case. It gives me the MAX likes and distinct the post id´s but only the once that r different to the max one. If there r 3 times the same entry, it will not be distinct. I need to filter out the double once. Hope someone can help here.
SELECT p.*
FROM posts p
INNER JOIN
(SELECT post_id, MAX(likes) AS MaxLikes
FROM posts
GROUP BY post_id) grouped
ON p.post_id = grouped.post_id
AND p.likes = grouped.MaxLikes
ORDER BY p.post_id ASC
Result looks like this:
ID | post_id | likes | somemorestuff...
2 | 1000 | 20 | ...
3 | 1001 | 7 | ...
4 | 1002 | 11 | ...
5 | 1003 | 19 | ...
6 | 1003 | 19 | ...
8 | 1004 | 17 | ...
9 | 1005 | 6 | ...
You need subquery with correlation approach :
select p.*
from posts p
where p.likes = (select max(p1.likes) from posts p1 where p1.post_id = p.post_id);
If you're using MySql 8+, you can try this:
Select * from
(Select *, Row_Number() over (partition by post_id order by likes desc) as ranking)c
where ranking = 1
Try this
Select max(id) as id, post_id, likes
From posts
Where (post_id, likes) in (Select post_id, max(likes) from posts group by post_id)
group by post_id, likes
I have a points table, where important columns are:
id userid orderid
1 10 150
2 10 150
3 15 151
4 12 152
5 11 152
I need to find all orderid which have multiple/various userid. The result would be:
id userid orderid
4 12 152
5 11 152
I can do it in PHP, but I hope someone have time to help me with mysql query. What I have tried so far is probably irrelevant.
Use COUNT(DISTINCT) and HAVING to find orderid with multiple various userid.
SqlFiddleDemo
SELECT t.*
FROM tab t
JOIN (SELECT orderid, COUNT(DISTINCT userid)
FROM tab
GROUP BY orderId
HAVING COUNT(DISTINCT userid) > 1) AS sub
ON t.orderid = sub.orderid
ORDER BY t.id
If you want to get just the rows that have same orderid but different userid, use this:
SELECT P1.* FROM points P1
INNER JOIN points P2
ON P1.orderid = P2.orderid and P1.id != P2.id and P1.userid != p2.userid;
Note that this first select returns what you expect in your question:
+----+--------+---------+
| id | userid | orderid |
+----+--------+---------+
| 4 | 12 | 152 |
| 5 | 11 | 152 |
+----+--------+---------+
Now, if you want to return ANY orderid that is the same, regardless of userid, use this:
SELECT P1.* FROM points P1
INNER JOIN points P2
ON P1.orderid = P2.orderid and P1.id != P2.id;
In this case, it won't exclude the result with same id, returning
+----+--------+---------+
| id | userid | orderid |
+----+--------+---------+
| 1 | 10 | 150 |
| 2 | 10 | 150 |
| 4 | 12 | 152 |
| 5 | 11 | 152 |
+----+--------+---------+
I have table like
table_id item_id vendor_id category_id
1 1 33 4
2 1 33 4
3 1 33 2
4 2 33 4
5 2 33 2
6 3 33 4
7 3 33 4
8 1 34 4
9 1 34 4
10 3 35 4
Here table_id is primary key and table having total 98000 entries including 61 duplicate entries which I found by executing query
SELECT * FROM my_table
WHERE vendor_id = 33
AND category_id = 4
GROUP BY item_id having count(item_id)>1
In above table table_id 1,2 and 6,7 duplicate. I need to delete 2 and 7 from my table( Total 61 Duplicate Entries). How can I delete duplicate entries from my table using query with where clause vendor_id = 33 AND category_id = 4 ? I don't want delete other duplicate entries such as table_id 8,9
I cannot index the table, since I need to kept some duplicate entries which required. I need to delete duplicate with certain criteria
Please always take backup before running any deletion query.
Try using LEFT JOIN like this:
DELETE my_table
FROM my_table
LEFT JOIN
(SELECT MIN(table_id) AS IDs FROM my_table
GROUP BY `item_id`, `vendor_id`, `category_id`
)A
ON my_table.table_id = A.IDs
WHERE A.ids IS NULL;
Result after deletion:
| TABLE_ID | ITEM_ID | VENDOR_ID | CATEGORY_ID |
------------------------------------------------
| 1 | 1 | 33 | 4 |
| 3 | 1 | 33 | 2 |
| 4 | 2 | 33 | 4 |
| 5 | 2 | 33 | 2 |
| 6 | 3 | 33 | 4 |
See this SQLFiddle
Edit: (after OP's edit)
If you want to add more conditions, you can add it in outer WHERE condition like this:
DELETE my_table
FROM my_table
LEFT JOIN
(SELECT MIN(table_id) AS IDs FROM my_table
GROUP BY `item_id`, `vendor_id`, `category_id`
)A
ON my_table.table_id = A.IDs
WHERE A.ids IS NULL
AND vendor_id = 33 --< Additional conditions here
AND category_id = 4 --< Additional conditions here
See this SQLFiddle
What about this:
DELETE FROM my_table
WHERE table_id NOT IN
(SELECT MIN(table_id)
FROM my_table
GROUP BY item_id, vendor_id, category_id)
try below code...
DELETE FROM myTable
WHERE table_ID NOT IN (SELECT MAX (table_ID)
FROM myTable
GROUP BY table_ID
HAVING COUNT (*) > 1)
Try
DELETE m
FROM my_table m JOIN
(
SELECT MAX(table_id) table_id
FROM my_table
WHERE vendor_id = 33
AND category_id = 4
GROUP BY item_id, vendor_id, category_id
HAVING COUNT(*) > 1
) q ON m.table_id = q.table_id
After delete you'll have
| TABLE_ID | ITEM_ID | VENDOR_ID | CATEGORY_ID |
------------------------------------------------
| 1 | 1 | 33 | 4 |
| 3 | 1 | 33 | 2 |
| 4 | 2 | 33 | 4 |
| 5 | 2 | 33 | 2 |
| 6 | 3 | 33 | 4 |
| 8 | 1 | 34 | 4 |
| 9 | 1 | 34 | 4 |
| 10 | 3 | 35 | 4 |
Here is SQLFiddle demo
From your Question, I guess you need to remove the duplicate rows which has same values for the item_id,vendor_id and category_id like the rows having tabled_id 1 and 2. So it can be done by making the mentioned three columns unique together. So try the following,
alter ignore table table_name add unique index(item_id, vendor_id, category_id);
Note: I didnt test this yet, Will give sqlfiddle in sometime
I have a table with only numeric IDs
ID
1
2
3
4
5
6
7
8
9
10
And I want to break and concatenate (group) this ids into groups of 5s or 20s, ej.
GROUPS
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
How can I do this with SQL?
UPDATE:
SELECT with sorted ids
SELECT GROUP_CONCAT(id ORDER BY id) AS GROUPS
FROM `test`
GROUP BY (id - 1) DIV 5
Result:
GROUPS
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
26,27,28,29,30
31,32,33,34,35
SELECT with second unsorted table
SELECT GROUP_CONCAT(id ORDER BY id) AS GROUPS
FROM `test2`
GROUP BY (id - 1) DIV 5
Result:
GROUPS
3,5
10
12
16
23,24,25
32,35
43,44
47
55
61
68,70
77
84
89
91,92,95
97,100
For MySQL:
SELECT GROUP_CONCAT(id ORDER BY id) AS GROUPS
FROM yourtable
GROUP BY (id - 1) DIV 5
See it working online: sqlfiddle
For unsorted IDs:
SET #rank=0;
SELECT
id,
#rank:=#rank+1 AS rank,
GROUP_CONCAT(id ORDER BY id) AS GROUPS
FROM `test2`
GROUP BY (#rank ) DIV 5
And the result:
+----+------+----------------+
| id | rank | GROUPS |
+----+------+----------------+
| 1 | 1 | 1,3,5,7,9 |
| 13 | 7 | 11,13,15,17,19 |
| 29 | 15 | 21,23,25,27,29 |
| 31 | 16 | 31,33,35,37,39 |
| 45 | 23 | 41,43,45,47,49 |
| 51 | 26 | 51,53,55,57,59 |
| 61 | 31 | 61,63,65,67,69 |
| 77 | 39 | 71,73,75,77,79 |
| 81 | 41 | 81,83,85,87,89 |
| 93 | 47 | 91,93,95,97,99 |
+----+------+----------------+
Thanks a lot for your help, I could't know without your help!