Обновить записи с помощью соединения по условию в mysql

У меня 2 стола

utr_details

utr | utr_amt |match_flag(default 0)
1   |10       |0
1   |20       |0
1   |20       |0
2   |30       |0
2   |20       |0
2   |10       |0

export_data
utr | utr_sum_amt
1   | 50
2   | 100

Как вы можете видеть выше, сумма utr_amt в таблице utr_details для utr 1 равна 50, что равно utr_sum_amt в экспорте export_data для utr 1. Но сумма utr 2 в обеих таблицах не равна. Моя задача - обновить значение match_flag до 1, где сумма равна в обеих таблицах. В этом случае match_flag будет 1 для utr 1 в таблице utr_details. Пожалуйста, помогите мне сгенерировать запрос mysql. Можно ли добиться этого с помощью одного запроса?

🤔 А знаете ли вы, что...
MySQL предоставляет механизмы для ограничения доступа к данным на уровне пользователя и ролей.


32
3

Ответы:

Запрос мог бы выглядеть так:

UPDATE utr_details 
SET match_flag = 1
WHERE utr IN (
SELECT utr, utr_sum_amt, auto_sum.sum.correct
FROM export_data 
INNER JOIN 
(SELECT utr, SUM(utr_amt) AS sum_correct
FROM utr_details
GROUP BY utr) auto_sum
WHERE utr_sum_amt = auto_sum.sum.correct
)

Вот как это работает.

1) Рассчитайте фактические суммы:

SELECT utr, SUM(utr_amt) AS sum_correct
FROM utr_details
GROUP BY utr

2) Присоединитесь к export_data с этим новым выбором и добавьте предложение WHERE, чтобы выбрать только те строки, в которых суммы различаются.

3) Запустите UPDATE, используя приведенные выше результаты в качестве фильтра.


Решено

Возможно, здесь больше вопросов, чем это строго необходимо, но вы поняли ...

DROP TABLE IF EXISTS utr_details;

CREATE TABLE utr_details
(id SERIAL PRIMARY KEY
,utr INT NOT NULL
,utr_amt INT NOT NULL
,match_flag TINYINT NOT NULL DEFAULT 0
);

INSERT INTO utr_details VALUES
(1,1,10,0),
(2,1,20,0),
(3,1,20,0),
(4,2,30,0),
(5,2,20,0),
(6,2,10,0);

DROP TABLE IF EXISTS export_data;

CREATE TABLE export_data
(utr INT NOT NULL PRIMARY KEY
,utr_sum_amt INT NOT NULL
);

INSERT INTO export_data VALUES
(1, 50),
(2,100);

UPDATE utr_details a 
  JOIN 
     ( SELECT x.utr 
         FROM 
            ( SELECT utr
                   , SUM(utr_amt) utr_sum_amt 
                FROM utr_details 
               GROUP 
                  BY utr
            ) x 
         JOIN export_data y 
           ON y.utr = x.utr 
          AND y.utr_sum_amt = x.utr_sum_amt
     ) b 
    ON b.utr = a.utr 
   SET match_flag = 1;
Query OK, 3 rows affected (0.05 sec)

SELECT * FROM utr_details;
+----+-----+---------+------------+
| id | utr | utr_amt | match_flag |
+----+-----+---------+------------+
|  1 |   1 |      10 |          1 |
|  2 |   1 |      20 |          1 |
|  3 |   1 |      20 |          1 |
|  4 |   2 |      30 |          0 |
|  5 |   2 |      20 |          0 |
|  6 |   2 |      10 |          0 |
+----+-----+---------+------------+

UPDATE utr_details 
   JOIN (SELECT aggregates.utr 
         FROM   (SELECT utr, Sum(utr_amt) utr_total 
                 FROM   utr_details 
                 GROUP  BY utr) aggregates 
                JOIN export_data 
                  ON aggregates.utr = export_data.utr 
         WHERE  utr_total = utr_sum_amt) aggregates_equal 
     ON aggregates_equal.utr = utr_details.utr 
SET match_flag = 1;