Return duplicate records - mysql

I simply want to return duplicate records from a table. In my case, a record is duplicate if more than one record has the same value in col1, col2, col3, and col4.

SELECT col1, col2, col3, col4
, COUNT(*) AS cnt
FROM yourTable
GROUP BY col1, col2, col3, col4
HAVING COUNT(*) > 1
If there are additional columns that you want to be shown, you can JOIN the above to the table:
SELECT t.*
, dup.cnt
FROM yourTable t
JOIN
( SELECT col1, col2, col3, col4
, COUNT(*) AS cnt
FROM yourTable
GROUP BY col1, col2, col3, col4
HAVING COUNT(*) > 1
) AS dup
ON t.col1 = dup.col1
AND t.col2 = dup.col2
AND t.col3 = dup.col3
AND t.col4 = dup.col4

SELECT m.*
FROM (
SELECT col1, col2, col3, col4, COUNT(*)
FROM mytable
GROUP BY
col1, col2, col3, col4
HAVING COUNT(*) > 1
) md
JOIN mytable m
ON m.col1 = md.col1
AND m.col2 = md.col2
AND m.col3 = md.col3
AND m.col4 = md.col4

Related

Delete using group by with multiple columns

I want to delete all the rows which are returned by this query.
SELECT col1, col2, col3 FROM myTable GROUP BY col1, col2, col3 HAVING count(*) > 1;
I tried this, but it gives me a syntax error.
DELETE FROM myTable WHERE col1, col2, col3 IN (
SELECT col1, col2, col3 FROM (
SELECT col1, col2, col3 FROM myTable
GROUP BY col1, col2, col3 HAVING count(*) > 1 )
t );
Use an INNER JOIN with your table
DELETE t1 FROM myTable t1
INNER JOIN (
SELECT col1, col2, col3 FROM (
SELECT col1, col2, col3 FROM myTable
GROUP BY col1, col2, col3 HAVING count(*) > 1 )
t )
t2 ON t2.rcol1 = t1.rcol1 AND t2.col2 = t1.col AND t2.col3 = t1.col3;
But you you should test it on a test database, because i don't think that your select identifies the right rows, better would be to have a UNIQUE column, that would identify the correct rows, because this would delete all rows

MySQL - Performing a COUNT(*) for the current row

Here's my SELECT query:
SELECT col1, col3, col5, col8
FROM Table1
In my SELECT query, I want to perform a COUNT(*) exclusively for the current row.
I want something like this, but have no idea how I can get this:
SELECT col1, col3,
(
SELECT COUNT(*)
FROM table1 WHERE col3 = col3 value for current row
),
col5, col8
FROM Table1
What is the correct way to perform a COUNT(*) for the current row of a SELECT query resultset?
try this:
set #num := 0;
SELECT #num := #num+1 , col1, col3, col5, col8 FROM Table1
or other way:
SET #num := ( SELECT COUNT( * ) FROM Table1) ;
SELECT #num := #num -1 , col1, col3, col5, col8
FROM Table1
SELECT col1, col3,
(
SELECT COUNT(*)
FROM table1 WHERE id = A.Id
) Count,
col5, col8
FROM Table1 A
Found it.
If I write my query like this:
SELECT col1, col3,
COUNT(*) AS count,
col5, col8
FROM Table1
then I get COUNT of all the items in Table1 for all rows.
I actually wanted COUNT of all items for selective rows.
Like I may have col3 value appearing more than once. I actually want the count of all items for each col3.
So, GROUP BY clause is the solution.
SELECT col1, col3,
COUNT(*) AS Count,
col5, col8
FROM Table1
GROUP BY col3
Sorry, I think I wasn't able to explain my problem properly, so it confused a lot of people.. A very poor question. My bad.

How to test subqueries and return first non null result in MySQL?

I have a number of queries that contain multiple columns and I would like to run a single query to test them in order until one subquery returns results. I have found that a COALESCE statement only allows you to use and return a single column per sub query, which will not work with my data set:
subquery1 = SELECT col1, col2, col3 FROM table1 WHERE x = y
subquery2 = SELECT col2, col4, col7 FROM table2 WHERE t = p
subquery3 = SELECT col5, col8, col9 FROM table3 WHERE v = b
Is it possible to test each of these queries in order until one of them returns rows?
SELECT 1 AS o, col1, col2, col3
FROM table1
WHERE x = y
UNION ALL
SELECT 2 AS o, col2, col4, col7
FROM table2
WHERE t = p
UNION ALL
SELECT 3 AS o, col5, col8, col9
FROM table3
WHERE v = b
ORDER BY
o
LIMIT 1
If you want to return only the first query with rows, then you should write a procedure:
delimiter $$
create procedure myProc()
begin
if exists(SELECT col1, col2, col3 FROM table1 WHERE x = y) then
SELECT col1, col2, col3 FROM table1 WHERE x = y;
elseif exists(SELECT col2, col4, col7 FROM table2 WHERE t = p) then
SELECT col2, col4, col7 FROM table2 WHERE t = p;
elseif exists(SELECT col5, col8, col9 FROM table3 WHERE v = b) then
SELECT col5, col8, col9 FROM table3 WHERE v = b;
end if;
end $$
delimiter ;
And then call it:
call myProc();

Getting duplicate rows by several columns in MySQL

I'm trying to search duplicate rows by several columns in large table (near 18 000 rows). Problem is that queries take a lot of time, I tried this:
SELECT * FROM table_name a, table_name b
WHERE a.col1 = b.col1
AND a.col2 = b.col2
AND a.col3 = b.col3
AND a.col4 = b.col4
AND a.id <> b.id
and this:
SELECT *
FROM table_name
WHERE col1 IN (
SELECT col1
FROM table_name
GROUP BY col1
HAVING count(col1) > 1
)
AND col2 IN (
SELECT col2
FROM table_name
GROUP BY col2
HAVING count(col2) > 1
)
AND col3 IN (
SELECT col3
FROM table_name
GROUP BY col3
HAVING count(col3) > 1
)
AND col4 IN (
SELECT col4
FROM table_name
GROUP BY col4
HAVING count(col4) > 1
)
they both work, but too slow. Any ideas?
You can try using one joint GROUP BY statement like:
SELECT * FROM table_name
GROUP BY col1, col2, col3, col4
HAVING count(*) > 1
At the very least, it will look cleaner.
EDIT
To return all results as a sub-set for the previous column:
SELECT *
FROM table_name
WHERE col4 IN (
SELECT col4
FROM table_name
WHERE col3 IN (
SELECT col3
FROM table_name
WHERE col2 IN (
SELECT col2
FROM table_name
WHERE col1 IN (
SELECT col1
FROM table_name
GROUP BY col1
HAVING count(col1) > 1
)
)
)
This, in concept, should give you all results in a faster execution time.

How to select distinct on specific columns

I have few columns in a table
Col1, Col2, Col3, Col4
Now I want to select like this
SELECT DISTINCT (Col1, Col2, Col3), Col4
i.e. get the distinct based on only these three colunms.
Just GROUP BY Col1, Col2, Col3 with an aggregate function with the col4 like MAX, MIN, etc .. like so:
SELECT Col1, Col2, Col3, MAX(Col4)
FROM TableName
GROUP BY Col1, Col2, Col3
From a comment to another answer:
Can I get like this Col1, Col2 , Col3 and (Col4 in delimiter form)
Yes, you can use the for xml path.
select Col1,
Col2,
Col3,
(
select ',' + T2.Col4
from YourTable T2
where T1.Col1 = T2.Col1 and
T1.Col2 = T2.Col2 and
T1.Col3 = T2.Col3
for xml path(''), type
).value('substring((./text())[1], 2)', 'varchar(max)') as Col4
from YourTable as T1
group by T1.Col1, T1.Col2, T1.Col3
SQL Fiddle
The group by and distinct perform almost similar functionality in SQL:
SO both queries below are almost equivalent:
SELECT DISTINCT Col1, Col2, Col3 FROM tbl
SELECT Col1, Col2, Col3 FROM tbl GROUP BY Col1, Col2, Col3
select distinct ( Convert(varchar(255),Col1) +' '+
Convert(varchar(255),Col2)+' '+Convert(varchar(255),Col3)),
Col4 from clients