How to delete in mysql version 5.7 - mysql

how to delete duplicate rows in mysql version 5.7?
here's my code and im getting error
Error Code: 1241 Operand should contain 1 column(s)
How to fix please?
DELETE FROM table1 WHERE code AND cl_date IN (
SELECT code, cl_date FROM( SELECT
code, cl_date,
COUNT(cl_date)
FROM
table1) AS a
WHERE code = "code1" AND cl_date BETWEEN '2021-03-21' AND '2021-04-1'
GROUP BY cl_date
HAVING COUNT(cl_date) > 1)
ORDER BY cl_date ASC LIMIT 1;

According to my experience, it is not possible to have two columns with the "IN" operator. You can use the following command if you want to delete duplicate rows based on "code" and "cl_date" columns:
DELETE FROM table1 WHERE id Not IN (
SELECT
MIN(id)
FROM
table1
WHERE code = "code1" AND cl_date BETWEEN '2021-03-21' AND '2021-04-1'
GROUP BY cl_date
) and code = "code1"
This query keeps the first occurance of duplicate rows in the table by using "MIN(id)" and discards the others. The last row can be kept by using "MAX(id)" instead.

Here's code that works for me.
DELETE table1
FROM table1
INNER JOIN (
SELECT MAX(id) AS lastId, cl_date
FROM table1
WHERE code = "code1" AND closed BETWEEN '2021-03-01' AND '2021-04-30'
GROUP BY cl_date
HAVING COUNT(*) > 1) dup ON dup.cl_date = table1.cl_date
WHERE table1.id < dup.lastId

Related

SQL query to fetch rows which has same IDs but different values in other columns

I am Using the below table
The case_id for two rows. If the case Id is same then I would want to fetch the row that has Test_script_type as automation and ignore the manual. How can I achieve it with a SQL query..If there is only manual fetch the manual row. How can I achieve it with a SQL query. The Output would be like :
Help is appreciated. Thanks for your time In-advance
You could adress this with not exists:
select t.*
from mytable t
where
script_type = 'Automation'
or not exists (
select 1
from mytable t1
where
t1.case_id = t.case_id
and t1.script_name <> t.script_name
and t1.script_type = 'Automation'
)
You can also filter with a correlated subquery:
select t.*
from mytable t
where t.script_type = (
select min(t1.script_type) -- This gives priority to 'Automation' against 'Manual'
from mytable t1
where t1.case_id = t.case_id
)
SELECT t1.*
FROM `table` t1
LEFT JOIN `table` t2 ON t1.case_id = t2.case_id AND t1.script_type != t2.script_type
WHERE t1.script_type = 'automation' OR t2.case_id IS NULL
You could do something like the following:
WITH cte AS (
SELECT T1.CASE_ID, T1.SCRIPT_NAME, T1.SCRIPT_TYPE,
COUNT(T1.CASE_ID) OVER (PARTITION BY T1.CASE_ID) AS cnt
FROM table1 T1
)
SELECT cte.CASE_ID, cte.SCRIPT_NAME, cte.SCRIPT_TYPE
FROM cte
WHERE (cte.cnt > 1 AND UPPER(cte.SCRIPT_TYPE) = UPPER('AUTOMATION'))
OR cte.cnt = 1
The WITH statement adds a column counting how many times the case_id value is duplicated, which helps identify the rows you want to work with.
Here is an example of it working with the data you have provided: SQLFiddle
If you are using MSSQL Server, You may try below query -
SELECT *
FROM (SELECT CASE_ID, SCRIPT_NAME, SCRIPT_TYPE, ROW_NUMBER() OVER(PARTITION BY CASE_ID ORDER BY SCRIPT_TYPE) RN
FROM YOUR_TAB) T
WHERE RN = 1

How to delete duplicate rows in MySQL table?

I am using the following query, which I saw from another stackoverflow question but I am getting error.
delete from mytable
where myid not in (
select max(myid)
from mytable
group by myid2)
Error:
#1093 - Table 'mytable' is specified twice, both as a target for 'DELETE' and as a separate source for data
Edit 2:
I also tried this query:
delete from mytable
where myid in (
SELECT
myid, COUNT(*)
FROM
mytable
GROUP BY
myid2
HAVING
COUNT(*) > 1)
And got this error:
#1241 - Operand should contain 1 column(s)
In MySQL, you need to use a JOIN for this purpose. I assume you mean something like this:
delete t
from mytable t left join
(select max(myid) as myid
from mytable
group by myid2
) tt
on t.myid = tt.myid
where tt.myid is null;
Where ? is whatever you really want to group by. Your version will not delete anything because the group by and max() use the same column.

why the sql correct and the inner mechanism for run it?

the sql as follows come from mysql document. it is:
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
The document say It finds all rows in table t1 containing a value that occurs twice in a given column , and doesnot explain the sql.
t1 and t is the same table, so the
count(*) in subquery == select count(*) from t
, isn't it?
count(*) in subquery == select count(*) from t
is wrong. because in mysql you can't use it like that. so you have to run it like that to get result of same id having two rows.
if you want to get count of same occurrence,
SELECT id, name, count(*) AS all_count FROM t1 GROUP BY id HAVING all_count > 1 ORDER BY all_count DESC
And also you can get values as your query like this as well,
select * from t1 where id in ( select id from t1 group by id having count(*) > 1 )
The query contains a correlated subquery in WHERE clause:
SELECT COUNT(*) FROM t1 WHERE t1.id = t.id
It is called correlated because it is related to the main query via t.id. So, this subquery counts the number of records having an id value that is equal to the current id value of the record returned by the main query.
Thus, predicate
(SELECT COUNT(*) FROM t1 WHERE t1.id = t.id) = 2
evaluates to true for any row with an id value that occurs twice in the table.
SELECT * FROM t1 AS t
WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
This query goes through each record in t1 and then in the subquery looks into t1 again to see if in this case id is found 2 times (and only 2 times). You can do the same for any other column in t1 (or any table for that matter).
When you would like to see all values that are multiple times in the table, change WHERE 2 = by WHERE 1 <. This will also give you the values that are 3 times, 4 times, etc. in the table.
{
SELECT id,count( * )
FROM
MyTable
group by id
having count( * )>1
}
with this code, you can see the rows which repet more than one,
and you can change this query by yourself
How about using GROUP BY and HAVING:
SELECT id, count(1) as Total FROM MyTable AS t1
GROUP BY t1.id
HAVING Total = 2

Delete records based on another query in mysql

I have a query in MySQL based on which I am finding duplicate records of some columns.
select max(id), count(*) as cnt
from table group by start_id, end_id, mysqltable
having cnt>1;
This above query gives me the max(id) and the count of number of records that have start_id,end_id,mysqltable column values same.
I want to delete all the records that match the max(id) column of the above query
How can I do that?
I have tried like below
delete from table
where (select max(id), count(*) as cnt
from table group by start_id,end_id,mysqltable
having cnt>1)
But Unable to delete records
You can remove duplicate records using JOIN.
DELETE t1 FROM table t1
INNER JOIN
table t2
WHERE
t1.id > t2.id AND t1.start_id = t2.start_id AND t1.end_id = t2.end_id AND t1.mysqltable = t2.mysqltable;
This query keeps the lowest id and remove the highest.
I think so this command should work:
delete from table
where id in
( select max(id) from table
group by start_id, end_id, mysqltable
having count(*) > 1
);

MySql: generate random rows as a subquery

I've got a problem with a correlation inside a sub-query.
I have 2 tables :
- table1 : contains "groups" with a groupid, a groupename and a categoryid
- table2 : tells which people is member of which group (with fields: userid, groupid)
I would like to ask my database to give me :
all groups from a specific "category" with for each of them :
- the groupid, the groupname
- and a random selection of 4 members for each group
I followed the question MySQL select 10 random rows from 600K rows fast to generate 4 random members of a specific group.
It works well if I run the query separately.
but if I try to incorporate my sub-query inside my "general query" :
SELECT
g.groupid, g.groupname,
(
SELECT GROUP_CONCAT(table2.userid SEPARATOR ",")
FROM table2, (
SELECT userid AS uid
FROM table2
WHERE table2.groupid = g.groupid
ORDER BY RAND( )
LIMIT 4
) tmp
WHERE table2.userid = tmp.uid
) AS randomusers
FROM table1 AS g WHERE g.categoryid = ?
... I get a "Unknown column 'g.groupid' in 'where clause'" ERROR.
I tried to pass the subquery into a LEFT JOIN but I can't figure out how to do it properly as each of my attempts are unsuccessful.
Any help on this? Thanks :)
If I understood right, your query looks overly complicated
SELECT t1.groupid,
t1.groupname,
(SELECT GROUP_CONCAT(table2.userid) FROM table2 WHERE table2.userid = t1.userid ORDER BY RAND() LIMIT 4) AS `users`
FROM table1 AS t1
Have not tested it, but this query should return first four random elements for each group