find duplicates in pairs in mysql - mysql

I want to know how can I find duplicate value in a table over two columns combined.
suppose my table has fields as id || name || father_name || region || dob
now how can I find results set such as:
.ie I want to find all rows where three columns are same.

select t1.*
from your_table t1
join
(
select name, father_name, region
from your_table
group by name, father_name, region
having count(*) >= 3
) t2 on t1.name = t2.name
and t1.father_name = t2.father_name
and t1.region = t2.region

If you are using MySql 8.0, you could make use of window function. Below query with such function returns exact output:
select id, name, fatherName, country from (
select id,
name,
fatherName,
country,
count(id) over (partition by name, fatherName, country) cnt
from Tbl
) `a` where cnt > 1;

Actually, i also need this type of feature many times, where i need to compare all columns with same value except auto incremented primary key id column.
So, in that case i always use group by keyword.
Example,
SELECT A.*
FROM YourTable A
INNER JOIN (SELECT name,city,state
FROM YourTable
GROUP BY name,city,state
HAVING COUNT(*) > 1) B
ON A.name = B.name AND A.city = B.city AND A.state = B.state
You can append the number of columns which you want to compare
Hope, This might help you in your case also.

Related

MySQL take rows and override ones without user_id

I have table like this one:
I would like to all rows, but if there is user_id 5 if this case, override other rows which have no user_id.
I tried both with MAX(user_id) and GROUP BY country_name, but it still returns, wrong results.
Final result I'm expecting:
Try this;)
select t1.*
from yourtable t1
inner join (
select max(user_id) as user_id, country_name from yourtable group by country_name
) t2 on t1.country_name = t2.country_name and t1.user_id = t2.user_id
This is just a solution based on your sample data. If you have a variety of user_id, it should be more different.
As of SQL Select only rows with Max Value on a Column you can easily get rows with max value on a column by using both MAX(column) and GROUP BY other_column in one statement.
But if you want to select other columns too, you have to this in a subquery like in the following example:
SELECT a.*
FROM YourTable a
INNER JOIN (
SELECT country_name, MAX(user_id) user_id
FROM YourTable
GROUP BY country_name
) b ON a.country_name = b.country_name AND a.user_id = b.user_id

MySQL - Fetching lowest value

My database structure contains columns: id, name, value, dealer. I want to retrieve row with lowest value for each dealer. I've been trying to mess up with MIN() and GROUP BY, still - no solution.
Solution1:
SELECT t1.* FROM your_table t1
JOIN (
SELECT MIN(value) AS min_value, dealer
FROM your_table
GROUP BY dealer
) AS t2 ON t1.dealer = t2.dealer AND t1.value = t2.min_value
Solution2 (recommended, much faster than solution1):
SELECT t1.* FROM your_table t1
LEFT JOIN your_table t2
ON t1.dealer = t2.dealer AND t1.value > t2.value
WHERE t2.value IS NULL
This problem is very famous, so there is a special page for this in Mysql's manual.
Check this: Rows Holding the Group-wise Maximum/Minimum of a Certain Column
select id,name,MIN(value) as pkvalue,dealer from TABLENAME
group by id,name,dealer;
here you group all rows by id,name,dealer and then you will get min value as pkvalue.
SELECT MIN(value),dealer FROM table_name GROUP BY dealer;
First you need to resolve the lowest value for each dealer, and then retrieve rows having that value for a particular dealer. I would do this that way:
SELECT a.*
FROM your_table AS a
JOIN (SELECT dealer,
Min(value) AS m
FROM your_table
GROUP BY dealer) AS b
ON ( a.dealer= b.dealer
AND a.value = b.m )
Try following:
SELECT dealer, MIN(value) as "Lowest value"
FROM value
GROUP BY dealer;
select id, name, value, dealer from yourtable where dealer
in(select min(dealer) from yourtable group by name, value)
These answers seem to miss the edge case of having multiple minimum values for a dealer and only wanting to return one row.
If you want to only want one value for each dealer you can use row_number partition - group - the table by dealer then order the data by value and id. we have to make the assumption that you will want the row with the smallest id.
SELECT ord_tbl.id,
ord_tbl.name,
ord_tbl.value,
ord_tbl.dealer
FROM (SELECT your_table.*,
ROW_NUMBER() over (PARTITION BY dealer ORDER BY value ASC, ID ASC)
FROM your_table
) AS ord_tbl
WHERE ord_tbl.ROW_NUMBER = 1;
Be careful though that value, id and dealer are indexed. If not this will do a full table scan and can get pretty slow...

Diff value last two record by datetime

I have table with id, item_id, value (int), run (datetime) and i need select value diff betwen last two run per *item_id*.
SELECT item_id, ABS(value1 - value2) AS diff
FROM ( SELECT h.item_id, h.value AS value1, h2.value AS value2
FROM ( SELECT id, item_id, value
FROM table_name
GROUP BY item_id
ORDER BY run DESC) AS h
INNER JOIN ( SELECT id, item_id, value
FROM table_name
ORDER BY run DESC) AS h2
ON h.item_id = h2.item_id AND h.id != h2.id
GROUP BY item_id) AS h3
I believe this should do the trick for you. Just replace table_name to correct name.
Explanation:
Basicly I join the table with itself in a run DESC order, JOIN them based on item_id but also on id. Then I GROUP BY them again to remove potential 3rd and so on cases. Lastly I calculate the difference between them through ABS(value1 - value2).
SELECT t2.id, t2.item_id, (t2.value- t1.value) valueDiff, t2.run
FROM ( table_name AS t1
INNER JOIN
table_name AS t2
ON t1.run = (SELECT MAX(run) FROM table_name where run < t2.run)
and t1.item_id = t2.item_id)
This is assuming you want the diff between a record and the record with the previous run

need to show only the duplicate value in sql

i have table as
id----name----roll-----class
1----ram-------1-----2
2----shyam-----2-----3
3----ram-------1-----3
4----shyam-----2-----3
5----ram-------1-----2
6----hari------1-----5
i need to find the the duplicate row only that have common name, roll, class. so the expected result for me is.
id----name----roll-----class
1----ram-------1-------2
2----shyam-----2-------3
4----shyam-----2-------3
5----ram-------1-------2
i tried to get from the query below but here only one field is supported. i need all three field common. Please do help me in this. thanks
SELECT *
FROM table
WHERE tablefield IN (
SELECT tablefield
FROM table
GROUP BY tablefield
HAVING (COUNT(tablefield ) > 1)
)
You can use count() over().
select id, name, roll, class
from (select id, name, roll, class,
count(*) over(partition by name, roll, class) as c
from YourTable) as T
where c > 1
order by id
https://data.stackexchange.com/stackoverflow/query/63720/duplicates
this will retun only the duplicate entry one time:
select t.id, t.name, t.roll, t.class
from table t
inner join table t1
on t.id<t1.id
and t.name=t1.name
and t.roll = t1.roll
and t.class=t1.class
this will return what you require:
select distinct t.id, t.name, t.roll, t.class
from table t
inner join table t1
on t.name=t1.name
and t.roll = t1.roll
and t.class=t1.class
I'd suggest something like this
SELECT A.* FROM
Table A LEFT OUTER JOIN Table B
ON A.Id <> B.Id AND A.Name = B.Name AND A.Roll = B.Roll AND A.Class = B.Class
WHERE B.Id IS NOT NULL
Something like that should work (I did not test though):
select a1.*
from table a1, a2
where (a1.id != a2.id)
and (a1.name == a2.name)
and (a1.roll== a2.roll)
and (a1.class== a2.class);
It seems there are several proprosals here. If it is a query that you'll use in your code, beware of the cost of the queries. Try an 'explain' with your database.

MySQL: find MAX(var1) but return var2 of that entry instead

I have a table (or rather a long join) with fields (id, name, prio) where I group over id
SELECT id, group_concat(name)
FROM my_table
GROUP BY id
Now I'd also like to have a column with the name of the lowest prio score. Like
SELECT id, group_concat(name), min(prio)
FROM my_table
GROUP BY id
but instead of having the minimum value of prio I'd like to see the corresponding 'name'
Any idea?
I think you can make this a sub-query and then join it to the table something like:
SELECT * FROM (
SELECT id, group_concat(name), min(prio) AS lowest
FROM my_table
GROUP BY id ) foo
JOIN my_table mt ON foo.lowest = mt.prio AND foo.id=mt.id;
You cannot do it in one select , use joined select
SELECT a.id, ..., b.name FROM my_table JOIN ( SELECT id, name FROM my_table ORDER BY prio ASC LIMIT 1 ) AS b ON b.id = a.id ...