MySQL group_concat twice in SubQuery DISTINCT - mysql

I have table like this:
title name
1 ADAM SMITH
1 JACK SMITH
1 ROBERT ABADI
2 JACK SMITH
2 JAMES ANDERSON
3 JACK SMITH
When I call data with query looks like
SELECT title, name, group_concat(name) as gname
FROM sample
GROUP BY title
The result is:
1 ADAM SMITH ADAM SMITH,JACK SMITH,ROBERT ABADI
2 JACK SMITH JACK SMITH,JAMES ANDERSON
3 JACK SMITH JACK SMITH
Now, I want to group by name again. so I call this query and results is following.
SELECT title, name, group_concat(distinct gname)
FROM
(
SELECT title, name, group_concat(name) as gname
FROM sample
GROUP BY title
) sub
GROUP BY sub.name
1 ADAM SMITH ADAM SMITH,JACK SMITH,ROBERT ABADI
2 JACK SMITH JACK SMITH,JAMES ANDERSON,JACK SMITH
But I don't want to have the 'JACK SMITH' twice on last column.
I know the reason because the first group_concat() results is string that can't not applied with 'DISTINCT' clause.
Any suggestions are appreciated.

Use a JOIN to get co-authors:
SELECT s1.name, GROUP_CONCAT(DISTINCT s2.name)
FROM sample AS s1
JOIN sample AS s2 ON s1.title = s2.title
GROUP BY s1.name
DEMO
If you don't want to show an author as a co-author of himself, add AND s1.name != s2.name to the ON condition.

Related

mysql group sum same table

I have the following table:
id
name
type
score
1
john
orange
2345
2
john
yellow
5
3
john
black
5454540
4
jack
orange
1123
5
jack
yellow
1000
6
jack
black
86943
7
jane
orange
9876
8
jane
yellow
10000
9
jane
black
102233
comment;
id : inte
name : same name save more times to more rows,
score: it is int data
type : it has string data black,white,yellow,purple,orange
I'm using the following queries to calculate two score totals
SELECT name,sum(score) as `first`
FROM salary
WHERE type = 'orange'
SELECT name,sum(score) as `second`
FROM salary
WHERE type in ('black','yellow')
i want see result that ( all names must be group, single name.)
name
FirstScore
SecondScore
john
2345
5454545
jack
1123
87943
jane
9876
112233
Use a conditional SUM() to aggregate the values based on type:
SELECT name
, SUM(CASE WHEN type IN ('orange') THEN score END ) AS FirstScore
, SUM(CASE WHEN type IN ('yellow','black') THEN score END ) AS SecondScore
FROM salary
GROUP BY Name
Results:
name
FirstScore
SecondScore
john
2345
5454545
jack
1123
87943
jane
9876
112233
db<>fiddle here
Something like this (but this is untested):
SELECT
salary.name,
first.score as "first_score",
second.score as "second_score"
FROM salary
LEFT JOIN (SELECT name,sum(score) as score
FROM salary
WHERE type = 'orange'
) as first ON first.name = salary.name
LEFT JOIN (SELECT name,sum(score) as score
FROM salary
WHERE type in ('black','yellow')
) as second ON second.name = salary.name

MSSQL How to return only one match

I need to find matches in a table with the same data. For example, I have a list of people with their birthdates. I need to get a list of all the people in the database with the same birthdate.
name birthdate
Patrick 1971-06-07
John 1971-06-07
Mary 1972-06-07
Ashley 1972-06-07
When I run this query
select a.name, b.name as name2
from #tmp_duplicates a
join #tmp_duplicates b on b.birthdate = a.birthdate
where a.name != b.name
I get:
name name2
John Patrick
Patrick John
Ashley Mary
Mary Ashley
I only need it to match once, so I am looking for:
name name2
John Patrick
Ashley Mary
How do I write the query to only match once?

Removing redundant rows from db table

I have a database table like the following (bad design I know, but there are a ton of rows like this):
person1 | person2 | counselor
Jane Doe | John Doe | Mary Smith
John Doe | Jane Doe | Mary Smith
Frank Jones| Ann Jones | Tom Jones
Ann Jones | Frank Jones | Tom Jones
I'm trying to figure out how to just select one of the 'unique' rows so that a result would look like:
person1 | person2 | counselor
Jane Doe | John Doe | Mary Smith
Frank Jones| Ann Jones | Tom Jones
I've tried various things like SELECT distinct and SELECT MIN(person1), etc., but am striking out.
You will have 6 permutations of (person1,person2,counselor) and you can use union with all of them. Finally use a where clause so only one row per combination will be returned.
Fiddle with sample data
select * from (
select person1,person2,counselor
from tablename
union
select person1,counselor,person2
from tablename
union
select person2,person1,counselor
from tablename
union
select person2,counselor,person1
from tablename
union
select counselor,person2,person1
from tablename
union
select counselor,person1,person2
from tablename) t
where person1 < person2 and person2 < counselor
SQL Fiddle Demo
I include a case where no reverse duplicated and also another case where person1 = person2, also include P2.* in select just for debug.
SELECT P1.person1, P1.person2, P1.counselor, P2.*
FROM patient P1
LEFT JOIN patient P2
ON P1.person1 = P2.person2
AND P1.person2 = P2.person1
AND P1.counselor = P2.counselor
WHERE
concat(P1.person1, P1.person2) <= concat(P2.person1, P2.person2)
OR P2.person1 is null
When P2 is NULL mean there isn't a reverse combination of person1, person2
But when the combination exists only choose the smaller one as string concatenation.
With ranked_records AS
(
select *,
ROW_NUMBER() OVER(Partition By person1, person2, counselor
Order By person) [ranked]
from address
)
select * from ranked_records
where ranked > 1
For more detail, like how to delete latest records and keep the older one.
For MySql and if you have Id, try this:
DELETE A1
From Address A1
Where Exists (Select * From Address A2
Where A2.person1= A1.person1
AND A2.person2 = A1.person2
AND A2.counselor = A1.counselor
AND A1.AddressID > A2.AddressID)

Count appearances of a value in any column of a table

How can I count up the total appearances of a value in multiple columns?
Raw Table:
col1 col2
---- ----
don sam
jon sam
mike lisa
sam lisa
lisa beth
Result:
name appearances
---- -----------
don 1
sam 3
jon 1
mike 1
lisa 3
beth 1
I've tried writing a join where getting the total count is a subquery, but this seems awkward. I'm assuming MySQL has some way to handle this nicely.
Here's one way using UNION ALL:
select name, count(1) cnt
from (
select col1 as name from yourtable
union all
select col2 from yourtable
) t
group by name
SQL Fiddle Demo
Results:
NAME CNT
-----------
beth 1
don 1
jon 1
lisa 3
mike 1
sam 3
try this
select name , count(*) as appearances from
(
select col1 as name from Raw
union all
select col2 as name from Raw
)t
group by name
DEMO HERE

Filter duplicates from mysql result depending on column value

I'm having some problems working out how to return the desired rows from the following mysql table:
first_name last_name collection
==========================================
Bob Jones 1
Ted Jones 1
Bob Jones 1
Bob Jones 2
Ted Baker 2
I want to return the count of names based on columns 'first_name' and 'last_name'. Ordinarily it would just be a simple case of using 'group by first_name, last_name', so we would have the following result: a count of 3 for Bob Jones, 1 for Ted Jones, and 1 for Ted Baker.
However, the difficulty is the third column 'collection'. I need to exclude duplicate names between collections, but not within collections. So we'd include all names in the count for the first collection, but only include names in the count from the second collection if they do NOT occur in the first collection.
So, the desired result would be as follows: a count of 2 for Bob Jones, 1 for Ted Jones, and 1 for Ted Baker.
first_name last_name collection included?
========================================== ===============
Bob Jones 1 Yes
Ted Jones 1 Yes
Bob Jones 1 Yes
Bob Jones 2 No
Ted Baker 2 Yes
I have really tried to get my head around this but I am starting to run out of ideas. Any help would be hugely appreciated... thanks!
Perhaps
SELECT first_name, last_name, COUNT( DISTINCT collection) AS cnt
FROM yourtable
GROUP BY first_name, last_name
The COUNT DISTINCT would eliminate the duplicate Bob/Jones/1 records.
Is this what you are expecting?
SELECT u1.first_name, u1.last_name, u1.collection FROM users u1
WHERE u1.collection = (SELECT min(u2.collection)
FROM users u2 WHERE u1.first_name = u2.first_name
AND u1.last_name = u2.last_name);
http://www.sqlfiddle.com/#!2/bd086/7