mysql unable to display repeated entries in the view - mysql

I have the following table in the maria database
i am looking for the following output as a view
I have tried different approaches but it is not working.

Use group_concat() to aggregate the ids and do a self join of the table:
select t.id, t.name,
group_concat(tt.id order by tt.id) repeated
from tablename t left join tablename tt
on tt.name = t.name and tt.id <> t.id
group by t.id, t.name
order by t.id
See the demo.
Results:
| id | name | repeated |
| --- | ----- | -------- |
| 1 | John | 4,8 |
| 2 | Smith | 3 |
| 3 | Smith | 2 |
| 4 | John | 1,8 |
| 5 | Anna | |
| 6 | David | 7 |
| 7 | David | 6 |
| 8 | John | 1,4 |

Related

Find duplicate Values in a SQL Table and add unique value in a column

I have a table with locations and there are duplicates because there are locations with same name that belongs to different counties.
+------+-----------+-----------
| ID | location | parent_id |
+------+-----------+------------+
| 1 | Country | 0 |
| 2 | County 1 | 1 |
| 3 | County 2 | 1 |
| 4 | A | 2 |
| 5 | B | 2 |
| 6 | C | 2 |
| 7 | A | 3 |
| 8 | E | 3 |
| 9 | B | 3 |
+---- -+-----------+------------+
I would like to create and insert in column duplicate for each duplicate ID value . The result should look like this: ( Would be better to add ID in duplicate column to all duplicates excepting the one with smallest ID)
| ID | location | parent_id | duplicate|
+------+-----------+------------+----------+
| 1 | Country | 0 | |
| 2 | County 1 | 1 | |
| 3 | County 2 | 1 | |
| 4 | A | 2 | 4 |
| 5 | B | 2 | 5 |
| 6 | C | 2 | |
| 7 | A | 3 | 7 |
| 8 | E | 3 | |
| 9 | B | 3 | 9 |
+---- -+-----------+------------+---------+
I use this to list the rows:
SELECT a.* FROM mytable a
JOIN (SELECT location, COUNT(*)
FROM mytable
GROUP BY location
HAVING count(*) > 1 ) b
ON a.location= b.location
ORDER BY a.location
It looks like a window count can do what you want:
select t.*,
case when count(*) over(partition by location) > 1 then id end duplicate
from mytable t
This requires MySQL 8.0. In earlier versions, an alternative is a correlated subquery:
select t.*,
case when (select count(*) from mytable t1 where t1.location = t.location) > 1 then id end duplicate
from mytable t

How to get last records of SQL search with grouped names

I have this table:
+----+--------+-------------------+------------+
| id | name | mac | disk_usage |
+----+--------+-------------------+------------+
| 1 | simon | 00::00:00:00:01 | 10 |
| 2 | monica | 00::00:00:00:02 | 10 |
| 3 | andrew | 00::00:00:00:03 | 10 |
| 4 | amon | 00::00:00:00:04 | 10 |
| 5 | peter | 00::00:00:00:05 | 10 |
| 6 | rusty | 00::00:00:00:06 | 10 |
| 7 | simon | 00::00:00:00:01 | 22 |
| 8 | amon | 00::00:00:00:04 | 15 |
| 9 | monica | 00::00:00:00:02 | 18 |
| 10 | simon | 00::00:00:00:01 | 2 |
+----+--------+-------------------+------------+
When I put for search word "mon" I want this result:
+----+--------+-------------------+------------+
| id | name | mac | disk_usage |
+----+--------+-------------------+------------+
| 8 | amon | 00::00:00:00:04 | 15 |
| 9 | monica | 00::00:00:00:02 | 18 |
| 10 | simon | 00::00:00:00:01 | 2 |
+----+--------+-------------------+------------+
I am using this SQL command:
SELECT * FROM (SELECT test.* FROM test WHERE name LIKE "%mon%" ORDER BY id DESC)test GROUP BY name ORDER BY id DESC;
But I get this:
+----+--------+-------------------+------------+
| id | name | mac | disk_usage |
+----+--------+-------------------+------------+
| 4 | amon | 00::00:00:00:04 | 10 |
| 2 | monica | 00::00:00:00:02 | 10 |
| 1 | simon | 00::00:00:00:01 | 10 |
+----+--------+-------------------+------------+
Can someone help me with this problem?
use aggregation function max() by id, then join based on ID.
select * from test t
inner join
(select max(id) id, name
from test
where name like '%mon%'
group by name) t1 on t1.id = t.id
order by t.id asc
You cshould use a subquery for max mac group by name and join this to you original table
select * from test
inner join (
select name, max(mac) max_mac
from test
group by name
) t on t.name = test.name and t.max_mac = test.mac

Separated List with id's of related columns

Let's assume the following table:
| id | firstname | secondname | group |
|:-----------|------------:|:------------:|:------------:|
| 1 | Tom | Test1 | 111 |
| 2 | Jack | Test2 | 222 |
| 3 | Chris | Test3 | 333 |
| 4 | Lucy | Test4 | 333 |
| 5 | Joe | Test5 | 111 |
| 6 | John | Test6 | 111 |
how can i get a Query with the information, which others are in the same group?
I want to get something like this:
| id | firstname | secondname | group | others |
|:-----------|------------:|:------------:|:------------:|:------------:|
| 1 | Tom | Test1 | 111 | 5,6 |
| 2 | Jack | Test2 | 222 | |
| 3 | Chris | Test3 | 333 | 4 |
| 4 | Lucy | Test4 | 333 | 3 |
| 5 | Joe | Test5 | 111 | 1,6 |
| 6 | John | Test6 | 111 | 1,5 |
it would also be ok, if the separated list also includes the related id itself.
i tried this one, but i got only one row with all ids in the "others"-column
Select A.id,A.firstname,A.secondname,A.group,GROUP_CONCAT(B.id) from myTable A
inner join myTable B
on (A.group = B.group)
where a.id <> b.id
You can use a correlated subquery:
select a.*,
(select group_concat(b.id)
from mytable b
where b.group = a.group and b.id <> a.id
) as OthersInGroup
from myTable a;
Note: group is a keyword and a reserved word in MySQL, so I hope that is not the real name of the column.
A correlated subquery seems simpler than a left join and aggregation. With an index on mytable(group, id) it should have pretty good performance too.

MySQL complex ORDER BY issue

I have a complicated ordering issue in my query.
Raw, Unordered Data:
+------+--------+-----------+
| id | job_id | action_id |
+------+--------+-----------+
| 1 | 2 | 1 |
| 2 | 2 | 2 |
| 3 | 1 | 1 |
| 4 | 2 | 3 |
| 5 | 4 | 1 |
| 6 | 1 | 2 |
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| 9 | 4 | 2 |
+------+--------+-----------+
Required Ordering:
+------+--------+-----------+
| id | job_id | action_id |
+------+--------+-----------+
| 7 | 3 | 1 |
| 8 | 3 | 2 |
| | | | * blank lines added for clarity,
| 5 | 4 | 1 | not desired in actual data
| 9 | 4 | 2 |
| | | |
| 3 | 1 | 1 |
| 6 | 1 | 2 |
| | | |
| 1 | 2 | 1 |
| 2 | 2 | 2 |
| 4 | 2 | 3 |
+------+--------+-----------+
The theory behind this ordering:
the largest id is the most recently added entry
the most recent id with action_id of 1
followed by the entries with ascending action_ids that have the same job_id
then the next most recent action_id of 1
ad infinitum
EDIT: I'm not able to add columns to the table in order to aid in sorting, as I've seen in some other solutions to ordering questions.
Any help is greatly appreciated!
My best shot is this:
SELECT * FROM tbl
ORDER BY FIND_IN_SET(job_id,
(SELECT GROUP_CONCAT(job_id ORDER BY ID DESC)
FROM tbl WHERE action_id = 1));
I didn't find a way to do it easily, What do you think of the following code :
select c.id, c.job_id, c.action_id
from (select a.id, a.job_id, a.action_id, min(b.id) as related_id
from myTable a
inner join myTable b
on a.job_id=b.job_id
group by a.job_id) c
group by c.id
order by c.related_id desc, c.action_id

Don't know how to merge two MySQL tables

I'm new in SQL queries. I have a problem with the query.
I have table books:
+----+-------+--------+-----------+
| id | title | author | publisher |
+----+-------+--------+-----------+
| 1 | Book1 | 1 | 1 |
| 2 | Book2 | 1 | 2 |
| 3 | Book3 | 2 | 1 |
| 4 | Book4 | 2 | 2 |
| 5 | Book5 | 2 | 3 |
+----+-------+--------+-----------+
And I'm have another table, which contains copies of books with given book_id.
+----+---------+
| id | book_id |
+----+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |
| 9 | 5 |
+----+---------+
All I need is to merge these two tables into one to have table sorted by amount of book copies.
I found solution to get table sorted by amount of book copies:
select book_copies.book_id, count(*) total_count
from book_copies
group by book_id
having count(*) > 0
order by count(*) desc;
+---------+-------------+
| book_id | total_count |
+---------+-------------+
| 1 | 3 |
| 2 | 2 |
| 4 | 2 |
| 3 | 1 |
| 5 | 1 |
+---------+-------------+
Now I don't know how to merge them.
I've tried like this:
select books.title from books
left join
(select book_copies.book_id, count(*) total_count
from book_copies
group by book_id
having count(*) > 0
order by count(*) desc)
as total_table on books.id = total_table.book_id;
But all I get was this:
+-------+
| title |
+-------+
| Book1 |
| Book2 |
| Book3 |
| Book4 |
| Book5 |
+-------+
Could you help me please?
EDIT: by merging I meant smth like this:
+-------+--------+-----------+-----+
| title | author | publisher | tot |
+-------+--------+-----------+-----+
| Book1 | 1 | 1 | 3 |
| Book2 | 1 | 2 | 2 |
| Book4 | 2 | 2 | 2 |
| Book3 | 2 | 1 | 1 |
+-------+--------+-----------+-----+
Many thanks to #Marco for the answer!
Dmitriy
I think you could try:
SELECT b.title, b.author, b.publisher, COUNT(bc.book_id) AS tot
FROM books b LEFT JOIN book_copies bc
ON b.id = bc.book_id
GROUP BY b.id
EDITED:
If you want sort, you can try
SELECT * FROM
(SELECT b.title, b.author, b.publisher, COUNT(bc.book_id) AS tot
FROM books b LEFT JOIN book_copies bc
ON b.id = bc.book_id
GROUP BY b.id) g
ORDER BY g.tot DESC