SQLinfo.ru - Все о MySQL Highload++ 2017

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 19.07.2017 12:08:24

Pantela777
Завсегдатай
Зарегистрирован: 06.06.2016
Сообщений: 39

Обновлять данные через JOIN

Имется таблица base где надо обновлять 2 поля short_amount и long_amount исходя из таблицы transactions.

Из таблицы transactions значение можно запросить по:
Для short_amount =

SELECT SUM(amount_fee) FROM transactions WHERE loan_type = 1 GROUP BY transactions.base_id

Для long_amount =
SELECT SUM(amount_fee) FROM transactions WHERE loan_type = 2 GROUP BY transactions.base_id


Ну и связать их надо через
base.id = transactions.base_id


спс.Ув.

Отредактированно Pantela777 (19.07.2017 12:08:57)

Неактивен

 

#2 19.07.2017 14:45:49

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Обновлять данные через JOIN

что-то вроде этого

UPDATE base b
  JOIN (SELECT base_id, SUM(amount_fee) amount_fee FROM transactions WHERE loan_type = 1 GROUP BY 1) t ON b.id=t.base_id
set short_amount = amount_fee;

UPDATE base b
  JOIN (SELECT base_id, SUM(amount_fee) long_amount FROM transactions WHERE loan_type = 2 GROUP BY 1) t ON b.id=t.base_id
set long_amount  = long_amount;

Неактивен

 

#3 19.07.2017 15:09:51

Pantela777
Завсегдатай
Зарегистрирован: 06.06.2016
Сообщений: 39

Re: Обновлять данные через JOIN

спс, немного подправил,

UPDATE base b
  JOIN (SELECT base_id, SUM(amount_fee) as amount_fee FROM transactions WHERE loan_type = 1 GROUP BY 1) t ON b.id=t.base_id
  SET b.short_amount = amount_fee;

UPDATE base b
  JOIN (SELECT base_id, SUM(amount_fee) as amount_fee FROM transactions WHERE loan_type = 2 GROUP BY 1) t ON b.id=t.base_id
  SET b.long_amount  = amount_fee;


вроде работает, для оптимизации надо добавить:
1. только те записи обновить у которых base.status = 3
2. Добавить LIMIT 1, т.к. только одна запись надо обновить в base таблице
3. Может можно как-то через один UPDATE написать оба SET-а, что бы 2 раза не бежать по записам...

спс.Ув.

Отредактированно Pantela777 (19.07.2017 16:13:51)

Неактивен

 

#4 19.07.2017 15:55:07

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Обновлять данные через JOIN

немного напутали с названиями полей, посмотрите внимательно.

3.

UPDATE base b
  JOIN (SELECT base_id,
    SUM(CASE WHEN loan_type = 1 then amount_fee END) as sum_fee_st,
    SUM(CASE WHEN loan_type = 2 then amount_fee END) as sum_fee_ln
  FROM transactions GROUP BY 1) t ON b.id=t.base_id
  SET b.short_amount = sum_fee_st, b.long_amount  = sum_fee_ln;

Отредактированно klow (19.07.2017 15:56:36)

Неактивен

 

#5 19.07.2017 16:23:12

Pantela777
Завсегдатай
Зарегистрирован: 06.06.2016
Сообщений: 39

Re: Обновлять данные через JOIN

но тогда если loan_type = 1  или loan_type = 2 не найденно, тогда он прописывает NULL, получаеться что бы пред. значение он будет затерять...
Да и вобще я думаю через один UPDATE быстрее будет работать ведь? т.к. один раз пробежит и уже внутри WHERE определит что делать, а так 2 раза бежит...

А по 1 и 2 есть варианты?

Неактивен

 

#6 19.07.2017 16:46:04

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Обновлять данные через JOIN

Исправил

UPDATE base b
  JOIN (SELECT base_id,
    SUM(CASE WHEN loan_type = 1 then amount_fee END) as sum_fee_st,
    SUM(CASE WHEN loan_type = 2 then amount_fee END) as sum_fee_ln
  FROM transactions
  WHERE loan_type IN (1,2)
  GROUP BY 1) t ON b.id=t.base_id
  SET b.short_amount = IFNULL(sum_fee_st, b.short_amount), b.long_amount  = IFNULL(sum_fee_ln,b.long_amount);

1. Что мешает добавить WHERE base.status = 3?
2. Если по base.status есть индекс то смысла не имеет. Если индекса нет, можно добавить если точно знаете, что будет только одно значение.

Отредактированно klow (19.07.2017 16:46:37)

Неактивен

 

#7 19.07.2017 17:10:30

Pantela777
Завсегдатай
Зарегистрирован: 06.06.2016
Сообщений: 39

Re: Обновлять данные через JOIN

спс, но что-то не то...

#1406 - Data too long for column 'long_amount' at row 1



1. WHERE loan_type IN (1,2) - мне надо в таблице base определить, сейчас так? тогда получаеться WHERE loan_type IN (1,2) AND base.status = 3

2. Ну в base у меня разные записи, и обновление именно только WHERE loan_type IN (1,2) AND base.status = 3 надо выполнить. Индоксов на нём нету.

Неактивен

 

#8 19.07.2017 17:20:43

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Обновлять данные через JOIN

Проверьте тип данных в столбце long_amount.
1. Если поле base.id уникальное (ключевое), то смысла в WHERE base.loan_type IN (1,2) нет никакого. Даже есть сомнение в необходимости поля base.loan_type. Скорее всего это ошибка.
2. Аналогично и по base.status и LIMIT не нужны если поле base.id уникальное (ключевое).

Отредактированно klow (19.07.2017 17:28:27)

Неактивен

 

#9 19.07.2017 20:17:49

Pantela777
Завсегдатай
Зарегистрирован: 06.06.2016
Сообщений: 39

Re: Обновлять данные через JOIN

1 и 2. Ну base.id у меня уникальное, только я не понимаю почему вы на него делаете акцент, WHERE base.loan_type IN (1,2) мне ведь надо для того что бы только эти записи достать из base, и по ним искать потом суммы, и эти записи потом обновить, т.е. в base у меня ещё есть где loan_type = 3 или loan_type = 4, а они мне не нужны. - если это ясно. тогда тут у меня только одна догадка, я бегу по записям суммы и когда из нахожу их потом обновляю в base. исходя из этого у меня не может быть перебор другой записи т.к. я определённо base.id беру, НО мне надо как-то сливаться изначательно из base таблицы... т.к. вней у меня могут быть 5000 записией и только 1000 мне надо обновить, поэтому именно там я хочу определить loan_type IN (1,2), иначе сейчас получаеться что всегда будет происходить подсчёт сумму в transaction и всегда будет происходить обновление в base, что не особо верно...

Отредактированно Pantela777 (19.07.2017 20:18:42)

Неактивен

 

#10 22.07.2017 08:15:26

klow
Активист
Зарегистрирован: 06.12.2014
Сообщений: 236

Re: Обновлять данные через JOIN

Добрый день!
Если поле  loan_type используется в двух таблицах, то, вероятнее всего, нарушается принцип реляционных баз данных, что данные не должны повторятся.
Условие base.status = 3 у меня вызывает сомнение, но не зная деталей однозначный вывод сделать сложно.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson