how to get duplicate data from table with sql - mysql

I have a table directors and need to get all duplicated rows
Checking columns is name and phone_number
Table directors
uuid
name
phone_number
5esd
ari
111-222-333
6dcv
lee
111-222-333
56js
poo
667-784-343
tug8
ari
866-653-343
I need these rows:
uuid
name
phone_number
5esd
ari
111-222-333
6dcv
lee
111-222-333
tug8
ari
866-653-343
ecause two upper rows has same phone number and last record has same name as first row
What I tried is
select d1.* from directors as d1
join (
select d2.* from directors d2
group by `d2`.`uuid`
having count(d2.phone_number) > 1
or count(d2.name) > 1
) d2 on d1.uuid = d2.uuid;

Just one of possible options:
select t.* from t
join (
select phone_number from t group by phone_number having count(phone_number) > 1
) d on t.phone_number = d.phone_number;
https://sqlize.online/sql/psql14/f7d63b0d5d06a4d6d428798da644dcbb/
One more example:
select t.* from t
join t t_copy using(phone_number)
where t.uuid != t_copy.uuid;
https://sqlize.online/s/MW

A couple of options you can use:
select *
from t
where exists (
select * from t t2
where t2.phone_number = t.phone_number and t2.uuid != t.uuid
);
select * from (
select *, Count(*) over(partition by phone_number) cnt
from t
)t
where cnt > 1

Related

How to select only one data from duplicate data in mysql?

I have table bio
ID Name Country Address
1 Dan America A
2 Dan Japan B
3 Dan Canada C
4 Marcus China D
5 Kurtis Nepal E
6 Kurtis Mexico F
7 Jack Indonesia G
I need to select only one from the duplicate value of column "Name". I expect the result like this.
ID Name Country Address
1 Dan America A
4 Marcus China D
5 Kurtis Nepal E
7 Jack Indonesia G
I used this query
SET SESSION sql_mode = ( SELECT REPLACE ( ##sql_mode, 'ONLY_FULL_GROUP_BY', '' ) );
Select * from bio group by name;
Is there any other way without using SET SESSION sql_mode = ( SELECT REPLACE ( ##sql_mode, 'ONLY_FULL_GROUP_BY', '' ) ); since if i didn't use that, it return error.
I have tried answer with forpass answer but it run very slow. Here is the Explain query.
id select_type table type possible_keys rows filtered Extra
1 PRIMARY b ALL 1095012 100.00 Using where
2 DEPENDENT SUBQUERY t ALL PRIMARY,semua 1095012 3.33 Range checked for each record (index map: 0x3)
You can do it with NOT EXISTS:
SELECT b.*
FROM bio b
WHERE NOT EXISTS (
SELECT 1
FROM bio t
WHERE t.Name = b.Name AND t.ID < b.ID
)
It can be easily achieved in MySQL 8.0 using the ROW_NUMBER() OVER (PARTITION BY ) window function. But in 5.7 you have to emulate the same function with variables. Something like below.
SELECT ID, Name, Country, Address
FROM (
SELECT *, IF (#prev <> name, #rn: = 0, #rn),
#prev: = Name,
#rn: = #rn + 1 AS rn
FROM bio,
(SELECT #rn: = 0 ) rn,
(SELECT #prev: = '') prev
ORDER BY Address ASC
) t
WHERE rn = 1;
Alternatively you can use simple join to avoid mentioning the column names
SELECT b1.*
FROM bio b1
JOIN
(
SELECT Name, Min(ID) AS ID FROM bio
GROUP BY Name
) b2
ON b1.Name = b2.Name AND b1.ID = b2.ID;

Mysql - Calculate rank grouped by two columns

I have a mysql table like so:
Tbl
[Username Number Type]
manos 5 A
manos 6 B
maria 2 A
maria 3 B
maria 1 C
nick 7 A
nick 4 C
aaron 8 A
I want to create a view where I will have the ranks of each user (by larger Number), grouped by Type, in comparison to the other users in each Type. More specifically, I would like the output to be:
[Username Rank Type]
manos 3 A
manos 1 B
maria 4 A
maria 2 B
maria 2 C
nick 2 A
nick 1 C
aaron 1 A
I have tried the following:
select Username, count(*) as Rank, Type
from Tbl as aw
where
Number <= (
select Number
from Tbl
where Type = aw.Type
)
group by Username, Type
The result is that I get the Subquery returns more than 1 row error.
Any help would be appreciated!
Edit: changed the names of columns as suggested. Also a fiddle to help: http://sqlfiddle.com/#!9/55ec3f
Edit 2: Some clarification and corrections to the "all combinations rank".
Lets say we have another table called Teams:
Teams
[Username Team]
manos T1
manos T2
maria T1
maria T2
nick T1
nick T2
aaron T3
In this case I want to extract ranks on each combination of group(s) and Types, i.e. for Manos I would like:
Rank against people in T1 with type A
Rank against people in T2 with type A
Rank against people in T1 with type B
Rank against people in T2 with type B
Rank against people in T1 AND T2 with type A
Rank against people in T1 AND T2 with type B
For the sake of sanity, I renamed your group column...
SELECT username
, user_group
, number
, CASE WHEN #prev=user_group THEN #i:=#i+1 ELSE #i:=1 END rank
, #prev:=user_group
FROM my_table x
, (SELECT #prev:=null, #i:=0) vars
ORDER
BY user_group
, number DESC;
Correct code:
select Username, (select Number
from Tbl as t
where t.Type = aw.Type and t.Username = aw.Username) as Rank, Type from Tbl as aw where
Number <= (
select Number
from Tbl as t
where t.Type = aw.Type and t.Username = aw.Username
) group by Username, Type

JOIN, GROUP BY, SUM Issue Mysql

Assuming I have this table
tableA
ID value
1 5
1 5
3 10
2 4
2 2
1 2
tableB
ID Name
1 apple
2 carrot
3 banana
If the expected max value of apple is 10, carrot is 5, and banana is 15 the output table would be
table output
ID Name value
1 apple 12
2 carrot 6
what SQL statement I need to solve this?
what I have done so far:
SELECT a,ID, b.name , sum(a.valueSUM) AS value FROM tableA a
INNER JOIN tableB b
ON a.id = b.id
GROUP BY id
what options i need on the WHERE clause to pull this off?
The inner subquery groups them normally and then the main query is what deals with limiting the results.
SELECT * FROM
(select
b.id,
b.name as name,
SUM(a.value) as the_sum
from tableA a inner join tableB b
on a.Id = b.id
group by b.name, b.id
) y
where (name = 'apple' and the_sum >= 10) OR
(name = 'banana' and the_sum >= 15) OR
(name = 'carrot' and the_sum >= 5)
It seems your sample data has changed, please try this. I thought the ID doesnt have to follow tableA/tableB's id and the id is auto-generated as per the results.
Would be nice if you have another table that sets the threshold per name
Assuming threshold can be specified in tableB (makes sense):
SELECT a.ID, b.name, sum(a.value) AS value
FROM tableA a
INNER JOIN tableB b
ON a.id = b.id
GROUP BY a.ID, b.name, b.Threshold
HAVING sum(a.value) > b.Threshold;
Demo: http://rextester.com/ICOQF10295
SELECT TableB.id, TableB.Name, MAX(TableA.value) AS Value
FROM TableA INNER JOIN TableB ON
TableA.id = TableB.id
GROUP BY TableB.id, TableB.Name
Instead of SUM, use MAX aggregate function
This works in SQL Server
--Existing tables
create table #tableA (ID int, value int)
create table #tableB (ID int, Name varchar(30))
insert into #tableA
select 1 , 5 union all
select 1 , 5 union all
select 3 , 10 union all
select 2 , 4 union all
select 2 , 2 union all
select 1 , 2
insert into #tableB
select 1 , 'apple' union all
select 2 , 'carrot' union all
select 3 , 'banana'
--Create new temporary table #tableC
create table #tableC (ID int, MAXvalue int)
insert into #tableC
select 1 , 10 union all
select 2 , 5 union all
select 3 , 15
select c.ID,b.Name, a.value from #tableC c
inner join #tableB b on b.ID = c.ID
inner join (
select ID,SUM(value) as value from #tableA
group by ID
) a on a.ID = c.ID
where a.value >= c.MAXvalue
drop table #tableA
drop table #tableB
drop table #tableC

MySQL - how to reorder records depending on counted quantity

Please help me to figure out how to get table like this:
ID Name City
-- ---- ----
1 A 2
2 C 1
3 E 3
4 B 2
5 D 2
6 G 3
7 F 2
... to be sorted like this:
ID Name City
-- ---- ----
1 A 2
4 B 2
5 D 2
7 F 2
3 E 3
6 G 3
2 C 1
in other words I'd like it to be reordered depending on quantity of Names in a City firstly, and by Name secondly.
Cities having more Names should go first.
This should do the trick:
select c.* from c
inner join (
select City, count(*) as cnt from c group by City
) a
on c.City = a.City
order by a.cnt desc, c.name asc
Here is SQL Fiddle
SELECT ID,NAME,CITY,(select count(*) from AS T2 where T2.CITY = T1.CITY) as CITYCOUNT FROM AS T1 order by CITYCOUNT DESC,NAME ;
OR
SELECT ID,NAME,CITY FROM AS T1 order by (select count(*) from AS T2 where T2.CITY = T1.CITY)DESC,NAME ;
Alternatively you can also do this:
ALTER TABLE ADD COLUMN CITYCOUNT INT(11) DEFAULT 0;
UPDATE T1 (select CITY,count(*) as CITYCOUNT from group by CITY) T2 SET T1.CITYCOUNT = T2.CITYCOUNT where T1.CITY = T2.CITY;
SELECT ID,NAME,CITY,CITYCOUNT FROM AS T1 order by CITYCOUNT DESC,NAME
I think your example is not correct, Cities with Value 3 should come on Top, for this you can try this query:
SELECT
ID, Name, City
FROM <TABLE>
ORDER BY City DESC, Name ASC;
Hope this is what you want.
Updated Answer:
SELECT
Id, Name, T.City
FROM <TABLE> T
INNER JOIN
(SELECT DISTINCT
City, Count(City) AS CITYCOUNT
FROM Table_7
GROUP BY City) TEMP ON TEMP.City = T.City
ORDER BY TEMP.CITYCOUNT DESC

Group by with union mysql select query

(SELECT COUNT(motorbike.`owner_id`) as count,owner.`name`,transport.`type` FROM transport,owner,motorbike WHERE transport.type='motobike'
AND owner.`owner_id`=motorbike.`owner_id`
AND transport.`type_id`=motorbike.`motorbike_id` GROUP BY motorbike.owner_id)
UNION ALL
(SELECT COUNT(car.`owner_id`) as count,owner.`name`,transport.`type` FROM transport,owner,car WHERE transport.type='car'
AND owner.`owner_id`=car.`owner_id`
AND transport.`type_id`=car.`car_id` GROUP BY car.`owner_id`)
The query above returns a result like this below,
count name
1 Linda
2 Mary
1 Steve
1 Linda
This query is to count how many transport that owned by an owner. Linda have one car and one motorcycle,so the result should:
count name
2 Linda
2 Mary
1 Steve
I have tried this query,but return error:
(SELECT COUNT(motorbike.`owner_id`),owner.`name`,transport.`type` FROM transport,owner,motorbike WHERE transport.type='motobike'
AND owner.`owner_id`=motorbike.`owner_id`
AND transport.`type_id`=motorbike.`motorbike_id`)
UNION ALL
(SELECT COUNT(car.`owner_id`),owner.`name`,transport.`type` FROM transport,owner,car WHERE transport.type='car'
AND owner.`owner_id`=car.`owner_id`
AND transport.`type_id`=car.`car_id`) GROUP BY motorbike.owner_id
Can anyone help me please?
select sum(qty), name
from (
select count(m.owner_id) as qty, o.name
from transport t,owner o,motorbike m
where t.type='motobike' and o.owner_id=m.owner_id
and t.type_id=m.motorbike_id
group by m.owner_id
union all
select count(c.owner_id) as qty, o.name,
from transport t,owner o,car c
where t.type='car' and o.owner_id=c.owner_id and t.type_id=c.car_id
group by c.owner_id
) t
group by name
This may be what your after:
SELECT Count(Owner_ID), Name
FROM (
SELECT M.Owner_ID, O.Name, T.Type
FROM Transport As T, Owner As O, Motorbike As M
WHERE T.Type = 'Motorbike'
AND O.Owner_ID = M.Owner_ID
AND T.Type_ID = M.Motorbike_ID
UNION ALL
SELECT C.Owner_ID, O.Name, T.Type
FROM Transport As T, Owner As O, Car As C
WHERE T.Type = 'Car'
AND O.Owner_ID = C.Owner_ID
AND T.Type_ID = C.Car_ID
)
GROUP BY Owner_ID
Try this EDITED:
(SELECT COUNT(motorbike.owner_id),owner.name,transport.type FROM transport,owner,motorbike WHERE transport.type='motobike' AND owner.owner_id=motorbike.owner_id AND transport.type_id=motorbike.motorbike_id GROUP BY motorbike.owner_id)
UNION ALL
(SELECT COUNT(car.owner_id),owner.name,transport.type FROM transport,owner,car WHERE transport.type='car' AND owner.owner_id=car.owner_id AND transport.type_id=car.car_id GROUP BY car.owner_id)