How to trim this table in mysql? - mysql

I am a sql noob and not sure how to explain this. So here is what I'm trying to achieve:
Original table
id node_id tag_id
-------------------------
1 10 3
2 10 4
3 10 1
4 11 7
5 11 8
Trimmed table:
id node_id tag_id
-------------------------
1 10 3
4 11 7
It should be simple but I really left clueless, so appreciate your help.

It is unclear exactly what you want to do, but the following produces the output you specify:
select min(id), node_id, min(tag_id)
from table t
group by node_id;
EDIT:
If you want to delete rows, then use join:
delete o
from original_table ot left join
(select min(id) as id
from original_table
group by node_id
) tokeep
on ot.id = tokeep.id
where tokeep.id is null;
This uses a left join to match to the minimum id for each node_id. These are kept -- only non-matches are deleted.

Related

how to remove duplicate entries from many to many relation using sql query

My tables look like this. my op and country is having many to many relationships with each other.
OP
id, name,.....
op_country
id, op_id, country_id
country
id, name, ...
my op_country filled like below
id op_id country_id
1 1 1
2 1 2
3 2 2
4 2 3
5 3 3
6 3 3
7 1 1
I want to remove my duplicate entries from op_country. Here I want to remove rows 6 and 7 since we already have rows with such values.
How can I do that.
DELETE t1
FROM op_country t1
JOIN op_country t2 USING (op_id, country_id)
WHERE t1.id > t2.id
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=247ebc5870a6ab10b64076ffb375797f
You want to delete entries for which exists a sibling with a lower ID:
delete from op_country
where exists
(
select null
from (select * from op_country) op2
where op2.op_id = op_country.op_id
and op2.country_id = op_country.country_id
and op2.id < op_country.id
);
The from (select * from op_country) is necessary instead of a mere from op_country due to some weird restriction in MySQL updates.

Select values on one column having an identical set of values on another column

I have a "relational table" that stores which post has which tags. Just like Stack Overflow, a post can have many tags, and a tag can have many posts.
The table only has two columns and it looks like this:
pid tid
1 3
1 4
2 1
2 3
2 4
3 1
3 3
3 4
4 1
4 3
5 1
5 3
6 2
6 4
In the above table, post 2 and 3 have an identical set of tags (values on another column tid), and so are post 4 and 5.
I want to select all posts (post IDs) where there exists another post with the same set of tid, so the query should return 2 3 4 5 from column pid.
I'm running on MariaDB 10.1.38.
Here's my own attempt but apparently it fails:
SELECT p.pid
FROM post_tags AS p
WHERE EXISTS (
SELECT *
FROM post_tags AS p2
WHERE
GROUP_CONCAT(p.tid SEPARATOR ',') = GROUP_CONCAT(p2.tid SEPARATOR ',')
GROUP BY p2.pid
)
GROUP BY p.pid;
MariaDB told me:
ERROR 1111 (HY000): Invalid use of group function
GROUP_CONCAT() is an aggregate function, so you can't apply it in the WHERE clause, as it's evaluated in the SELECT clause (this happens after WHERE).
Also note, that you should add an ORDER BY in the GROUP_CONCAT() function. There's no guaranteed order in a relational database, unless you specifically specify it.
You could do it like this:
SELECT t1.pid FROM
(
SELECT
pid, GROUP_CONCAT(tid ORDER BY tid) AS gctid
FROM t t1
GROUP BY pid
) t1
JOIN (
SELECT
pid, GROUP_CONCAT(tid ORDER BY tid) AS gctid
FROM t t1
GROUP BY pid
) t2 ON t1.pid != t2.pid AND t1.gctid = t2.gctid
see it working live in an sqlfiddle

Mysql count(*) based in two relations

I would like to count(*) how much customers have created a post or made a comment. If the same customer has made several posts and comments, it should count only once.
Customer Table:
ID Name ...
1 Jonh
2 Mark
3 King
4 Doe
Post Table:
ID USER_ID...
1 1
2 1
3 3
4 1
Comment Table:
ID USER_ID...
1 1
2 3
3 3
4 4
It should return count(*) = 3
(user_id: 1, 3 and 4).
Try this one. It worked for me and returns what you're looking for:
SELECT COUNT( USER_ID ) AS TOTAL
FROM (
SELECT USER_ID
FROM POSTS
UNION
SELECT USER_ID
FROM COMMENTS
)X
I used POSTS and COMMENTS as table names bc I was unsure what your exact table names are, so make sure to change these in your query.
This should work:
SELECT COUNT(DISTINCT USER_ID) FROM (
SELECT USER_ID FROM POST_TABLE
UNION
SELECT USER_ID FROM COMMENT_TABLE
)

Sequelize find two users in same group

user_id | group_id
------------------
5 3
6 1
6 3
7 1
7 2
8 2
My join table looks like this. The query I'm trying to accomplish is finding if two user_ids have a matching group_id.
I don't need any specific information back from the query, just a simple true or false.
Try this:
select
(select group_id from tbl where user_id = 'user_id1')
<=>
(select group_id from tbl where user_id = 'user_id2');

Select the first 5 rows and get count

I'm trying to write a mysql query:
first select 5 rows and then get count with a where
first select 5 rows
table
id user_id
--------
1 1
2 2
3 3
4 1
5 1
6 4
7 3
8 1
id user_id
----------
1 1
2 2
3 3
4 1
5 1
And then get count this table where user_id =1
result = 3
You can try somthing like that
Select count(*) From
(Select * From T
order by ID asc Limit 5) as child
where user_id = 1
Looks like you want to present two different result sets together. You need to use a JOIN for this. Something like so will do the trick for you.
SELECT T.*,c.cnt
FROM T
JOIN ( SELECT COUNT(*) cnt FROM T where user_id = 1 ) c
LIMIT 5
The subquery generates your count as a one-row resultset, and the JOIN (which lacks an ON condition) puts it into every row of your other resultset.
If you wanted to show five rows from your table, and have each row mention the count for the userid in that row, you could do this.
SELECT T.*,c.cnt
FROM T
JOIN ( SELECT COUNT(*) cnt, user_id
FROM T
GROUP BY user_id
) c ON T.user_id = c.user_id
LIMIT 5
The way that summary (COUNT(), etc) queries and detail queries work together is a little intricate, but you will figure it out.
Beware, though: If you do a LIMIT without first doing an ORDER BY, MySQL is free to return any five rows it pleases.