Getting duplicate rows by several columns in MySQL - 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.

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

Select query in IF statement MYSQL

In my MySql database, I want to create select query which should give output like this:
in my select query i want a column output as 1, if the column value present in a list returned by a select query else 0 .
Select col1,col2,
,IF col3 IN
((select col from tabl2 ),1,0)AS col5
from tbl1.
Thanks in Advance
SELECT col1, col2,
IF col3 IN ((select col from tabl2 ),1,0) AS col5
FROM tbl1
Using IF and subquery in MySQL
SELECT table1.column1, table1.column2,
(
SELECT IF (
(SELECT column3 FROM table1 WHERE column3 IN (SELECT column FROM table2)), 1, 0
)
) AS column_output
FROM table1
In general:
SELECT col1,
col2,
CASE WHEN col3 IN (select col from tabl2)
THEN 1
ELSE 0
END AS col5
FROM tbl1
Specific for MySQL:
SELECT col1,
col2,
col3 IN (select col from tabl2) AS col5
FROM tbl1

How to set priority on order by in MySQL based on search in columns?

I am doing simple MySQL query like:
SELECT * FROM `table` WHERE col1 LIKE = '%text%' OR col2 LIKE = '%text%'
What I need to do, is to sort all the results where the searched text was found in col1 first and after that I need to have results where the searched text was found in col2.
In a numeric context, boolean values are treated as integers where 0 is false and 1 is true, so you could just order by those terms:
SELECT *
FROM `table`
WHERE col1 LIKE '%text%' OR col2 LIKE '%text%'
ORDER BY col1 LIKE '%text%' DESC
for unsure the proper order you could union (for distinct result) and add an explict column for order
select col1, col2, col3, .... , coln
from (
SELECT col1, col2, col3, .... , coln , 1 my_order
FROM `table`
WHERE col1 LIKE = '%text%'
UNION
SELECT col1, col2, col3, .... , coln , 2
FROM `table`
WHERE col2 LIKE = '%text%'
) t
order by my_order
or union all for also duplicated values
select col1, col2, col3, .... , coln
from (
SELECT col1, col2, col3, .... , coln , 1 my_order
FROM `table`
WHERE col1 LIKE = '%text%'
UNION ALL
SELECT col1, col2, col3, .... , coln , 2
FROM `table`
WHERE col2 LIKE = '%text%'
) t
order by my_order
You can use UNION, to get the Select results separately, and combine them. Also, Union will ensure that duplicates are removed (rows which match both the conditions). If you want the duplicates also, then use UNION ALL.
Check the following:
SELECT *
FROM `table`
WHERE col1 LIKE = '%text%'
UNION
SELECT *
FROM `table`
WHERE col2 LIKE = '%text%'

Select from select with a count

Ok i believe I've done something similar before, but don't really remember how I did it.
Searching around gives me similar answer's but not solving my issue.
Ex1, This query is fine:
SELECT col1, count(*) as col3
FROM db.table
WHERE col2 = 0 group by col1
Ex2, But I need all where col3 is bigger than 1, so I tried:
Select *
FROM
(SELECT col1, count(*) as col3
FROM db.table
WHERE col2 = 0 group by col1)
WHERE col3 > 1;
# Not working
Ex3, I dont know why but this seems to be working:
SELECT col1, count(*) as col3
FROM db.table
WHERE col2 = 0
GROUP BY col1
HAVING count(*) > 1;
Ok, I just answered my own question when I read the error message from Mysql.
Select *
FROM
(SELECT col1, count(*) as col3
FROM db.table
WHERE col2 = 0 group by col1) temp
WHERE col3 > 1;
I was missing the alias.

calculate frequency using sql

I have a table in MySQL:
Col1 | Col2
a A
a B
c C
a B
i want to create a table like this:
col1 | col2 | freq
a A 0.33
a B 0.67
col1 is a specified item in Col1. col2 is distinct item that has occured with the specified item(i.e. a). freq column is the frequency of appearence of item in col2.
Can someone give me a hint of how to create such a query? Thanks a lot.
try this:
Select A.Col1, A.Col2, A.Count1 * 1.0 / B.Count2 As Freq
From (
Select Col1, Col2, Count(*) As Count1
From YourTableName
Group By Col1, Col2
) As A
Inner Join (
Select Col1, Count(*) As Count2
From YourTableName
Group By Col1
) As B
On A.Col1 = B.Col1
You can also use this which is coded in SQL server
DECLARE #Count INT;
SELECT #Count = COUNT(1) FROM YourTableName WHERE Col1 = 'a'
SELECT Col1, Col2, CAST(COUNT(1)* 1.00 /#Count AS DECIMAL(4,2) ) AS Frequency
FROM YourTableName
WHERE Col1 = 'a'
GROUP BY Col1, Col2
this way you have a better performance
With window functions
SELECT Col1, Col2, Count1*1.0 / Count2 AS freq
FROM (
SELECT
Col1,
Col2,
COUNT() OVER(PARTITION BY Col1, Col2) AS Count1,
COUNT() OVER(PARTITION BY Col1) AS Count2
FROM YourTableName
)
GROUP BY Col1, Col2