简体   繁体   中英

MySQL Update specified on Count criteria

I have the followin problem: I want to update all rows where COUNT criteria is greater 1, when not I want to update all except 1. It also should update per other_ID.

Dummytable:

+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
|  1 |        1 |        1 |           0 |
|  2 |        1 |        1 |           0 |
|  3 |        1 |     1234 |           0 |
|  4 |        2 |        2 |           0 |
|  5 |        2 |        1 |           0 |
|  6 |        2 |        1 |           0 |
|  7 |        4 |       20 |           0 |
|  8 |        4 |        1 |           0 |
|  9 |        4 |       60 |           0 |
| 10 |        5 |        1 |           0 |
| 11 |        5 |        1 |           0 |
| 12 |        6 |        5 |           0 |
+----+----------+----------+-------------+

excpected result:

+----+----------+----------+-------------+
| id | other_ID | cirteria | updatefield |
+----+----------+----------+-------------+
|  1 |        1 |        1 |           1 |
|  2 |        1 |        1 |           1 |
|  3 |        1 |     1234 |           0 |
|  4 |        2 |        2 |           0 |
|  5 |        2 |        1 |           1 |
|  6 |        2 |        1 |           1 |
|  7 |        4 |       20 |           0 |
|  8 |        4 |        1 |           1 |
|  9 |        4 |       60 |           0 |
| 10 |        5 |        1 |           0 |
| 11 |        5 |        1 |           1 |
| 12 |        6 |        5 |           0 |
+----+----------+----------+-------------+

my idea:

UPDATE pics AS tu SET updatefield=1 WHERE criteria=1 AND (select count(*) as cnt2 from pics where criteria>1 group by other_id)>1;

Error: Table 'tu' is specified twice, both as a target for 'UPDATE' and as a separate source for data

Also I have problems to geht the right count: SELECT other_id, count( ) as cnt FROM pics AS ts WHERE criteria=1 and (select count( ) as cnt2 from pics where criteria>1)>0 GROUP BY other_id;

i want to get cnt = 1 for other_id=5, but i get cnt=2

with SELECT other_id, COUNT(*) AS cnt2 FROM pics WHERE criteria>1 GROUP BY other_id;

I get all other_ids where i want to update the updatefield. But how can I connect it with the update? And how to get all except one for other_id=5

You can alias the sub query into another query, eg:

UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND other_id IN (
    SELECT a.id FROM (
        SELECT other_id AS id
        FROM test
        WHERE criteria > 1
        GROUP BY other_id
        HAVING COUNT(*) > 1
     ) a
  );

Here's the SQL Fiddle .

Update

This will update the ids for records with criteria 0 and >1 . Now, to update the records where there is more than one record with 1 criteria, you need to do something like this:

UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id IN (
    SELECT a.id FROM (
        SELECT MIN(id) AS id
        FROM test
        WHERE criteria = 1
        GROUP BY other_id
        HAVING COUNT(*) > 1
     ) a
  );

Thanks to @Darshan Mehtas answer and help I finally found the solution to solve it as I want.

Here's the complete solution:

UPDATE test
SET updatefield = 1
WHERE updatefield = 0 AND criteria = 1
AND id not IN (
  SELECT a.id FROM (
    SELECT id
    FROM test
    WHERE criteria>1
  ) a
)
AND id not IN (
  SELECT b.id FROM (
    SELECT id
    FROM test
    GROUP BY other_id
    HAVING COUNT(*) = 1
  ) b
)
AND id NOT IN (
  SELECT c.id FROM (
    SELECT id
    FROM test
    WHERE criteria=1 AND other_id NOT IN (
      SELECT other_id FROM test WHERE Criteria>1
    )
    GROUP BY other_id, criteria
    HAVING COUNT(criteria)>1
  ) c
);

Short description:

  1. First Subquery (a) filters IDs where a criteria is greater 1
  2. Second Subquery (b) filters IDs which have only on result
  3. Third Subquery (c) filters IDs Where criteria is 1an don't have any higher criteria and keeps, thansk grouping, the first result.

Only bad thing could be to keep in the last subquery (c) the first (mostly oldest) result instead of newest.

€dit: to keep the last result use this for subquery c instead:

AND id NOT IN (
  SELECT c.id FROM (
    SELECT id
    FROM test t1
    JOIN (SELECT other_id, max(id) maxid
          FROM test
          GROUP BY other_id) t2
    ON t1.otheR_id=t2.other_id AND t1.id=t2.maxid
    WHERE criteria=1 AND t1.other_id NOT IN (
      SELECT other_id FROM test WHERE Criteria>1
    )
    GROUP BY t1.other_id, criteria
  ) c
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM