count one column and update another in same table in mysql - mysql

I want to update one column based on count of another column in same table. I tried below query but no luck.
update
table
set conntype='Multiple'
where (select COUNT(cpemac) as nos from table group by cpemac) > 1
I get following error:
1093 - You can't specify target table 'table' for update in FROM clause

In MySQL, you need to use a JOIN:
update t join
(select cpemac, count(cpemac) as nos
from t
group by cpemac
) tt
on t.cpemac = tt.cpemac
set t.conntype = 'Multiple'
where cnt > 1;
This is a specific limitation of MySQL.
I should note, however, that your version would not work in any database. It would either update all rows or no rows, depending on the result of the subquery. There is no connection between the subquery and the outer query.

Related

How do I remove duplicates using DELETE FROM and a sub-query?

Notes:
The return from SELECT version() is 10.5.12-MariaDB-log
Default collation: utf8mb4_unicode-ci
Default charset: utf8mb4
Queries run using MySQL Workbench for Ubuntu Linux 8.0.29
My goal is to delete duplicated items in a table. I do not have any other table to use as a reference to check duplicates. I created a simple query and subquery that returns expected results:
SELECT * FROM messages WHERE id NOT IN
(SELECT id FROM
messages
WHERE
uid = '11899414026778263'
GROUP BY message_id , uid
ORDER BY created_at);
Despite setting SQL_SAFE_UPDATES to 0, a DELETE operation using the same data fails. I get a "QUERY Interrupted" message.
SET SQL_SAFE_UPDATES = 0;
DELETE FROM messages WHERE id NOT IN
(SELECT id FROM
messages
WHERE
uid = '11899414026778263'
GROUP BY message_id , uid
ORDER BY created_at);
SET SQL_SAFE_UPDATES = 1;
If I replace DELETE with SELECT *, the query returns results. Another StackOverflow answer said that querying based on a sub-query does not work in MySQL. Others say to use another table as reference instead of a subquery.
DELETE query results in 'Query Interrupted' MySQL Workbench?
This method works in some SQL implementations based on these answers and websites:
Delete Duplicates From a Table in SQL Server
Different ways to SQL delete duplicate rows from a SQL Table
How to delete duplicate rows in SQL Server?
order by is applied after grouping, so your order by is not sufficient to select the id with the lowest created_at for each group. Your query will fail under ONLY_FULL_GROUP_BY because the id returned by the subselect will be arbitrary within each group. You want to use first_value instead.
But it's easier just to not use a subquery:
delete m
from messages m
# is there a message we would prefer over this one?
inner join messages m2 on (m2.uid,m2.message_id)=(m.uid,m.message_id) and (m2.created_at,m2.id) < (m.created_at,m.id)

Remove Duplicate record from Mysql Table using Group By

I have a table structure and data below.
I need to remove duplicate record from the table list. My confusion is that when I am firing query
SELECT * FROM `table` GROUP BY CONCAT(`name`,department)
then giving me correct list(12 records).
Same query when I am using the subquery:
SELECT *
FROM `table` WHERE id IN (SELECT id FROM `table` GROUP BY CONCAT(`name`,department))
It returning all record which is wrong.
So, My question is why group by in subquery is not woking.
Actually as Tim mentioned in his answer that it to get first unique record by group by clause is not a standard feature of sql but mysql allows it till mysql5.6.16 version but from 5.6.21 it has been changed.
Just change mysql version in your sql fiddle and check that you will get what you want.
In the query
SELECT * FROM `table` GROUP BY CONCAT(`name`,department)
You are selecting the id column, which is a non-aggregate column. Many RDBMS would give you an error, but MySQL allows this for performance reasons. This means MySQL has to choose which record to retain in the result set. Based on the result set in your original problem, it appears that MySQL is retaining the id of the first duplicate record, in cases where a group has more than one member.
In the query
SELECT *
FROM `table`
WHERE id IN
(
SELECT id FROM `table` GROUP BY CONCAT(`name`,department)
)
you are also selecting a non-aggregate column in the subquery. It appears that MySQL actually decides which id value to be retained in the subquery based on the id value in the outer query. That is, for each id value in table, MySQL performs the subquery and then selectively chooses to retain a record in the group if two id values match.
You should avoid using a non-aggregate column in a query with GROUP BY, because it is a violation of the ANSI standard, and as you have seen here it can result in unexpected results. If you give us more information about what result set you want, we can give you a correct query which will avoid this problem.
I welcome anyone who has documentation to support these observations to either edit my question or post a new one.
You can JOIN the grouped ids with that of table ids, so that you can get desired results.
Example:
SELECT t.* FROM so_q32175332 t
JOIN ( SELECT id FROM so_q32175332
GROUP BY CONCAT( name, department ) ) f
ON t.id = f.id
ORDER BY CONCAT( name, department );
Here order by was added just to compare directly the * results on group.
Demo on SQL Fiddle: http://sqlfiddle.com/#!9/d715a/1

update statement after the condition met in select statement (mysql)

im having trouble with update if selected table is true...
IF this select statement is true
(SELECT COUNT(*) FROM Add_bonus WHERE value > 0) > 0)
THEN do
UPDATE bonus SET amount = amount + 10 WHERE 1
The if statement is only allowed in stored procedures, functions, and triggers in MySQL. You can do this with a single update:
UPDATE bonus
SET amount = amount + 10
WHERE exists (select 1 from Add_Bonus where value > 0);
Note that this query will update all rows in the bonus table when any appropriate row exists in the add_bonus table. That appears to be the intention of your original query. More commonly, there might be an employee id linking the two tables.
Also note the use of exists. This is typically more efficient than using count(*), because it can stop processing on the first row that matches.

Update mysql id column according to timestamp column

I'm wondering if its possible to update all of the mysql table ids column based on timestamps?
So, I have table with columns ID,TEXT,STAMP, and IDs are really out of order. It's possible to sort table on STAMP and then update all of IDs incremental from 1 (so the oldest entry will have ID of 1) with one single query?
UPDATE table_name a,(SELECT id,(#newid:=#newid+1) AS d FROM table_name,(SELECT #newid:=0) AS f ORDER BY stamp) AS g SET a.id = g.d WHERE a.id = g.id;
i think this will do.

How do I update MySQL table, using subselect

how can i write the query, to update the table videos, and set the value of field name to 'something' where the average is max(), or UPDATE the table, where average has the second value by size!!!
i think the query must look like this!!!
UPDATE videos
SET name = 'something'
WHERE average IN (SELECT `average`
FROM `videos`
ORDER BY `average` DESC
LIMIT 1)
but it doesn't work!!!
Two things here cause problems with my version of mysql (5.0.84)
1. Using limit not supported in subquery
2. Using table for update (videos) in subquery
I can't think of a good way to get around these problems. I'd suggest pulling the ids of hte rows you want to update out into your code and then executing the update in a second statement. If you are using pure sql and doing this by hand then you could always just select into a temp table and then update based on the ids that you insert there.
UPDATE videos
SET name = 'something'
WHERE videos.id IN (SELECT id
FROM `videos`
ORDER BY `average` DESC
LIMIT 1)