Обновите и выберите поле на основе таблицы foreignt, которая содержит несколько строк на основе самого последнего регистра - PullRequest
1 голос
/ 31 октября 2019

У меня следующая проблема с запросом, а затем с обновлением: у меня есть таблица основных пользователей следующим образом (я только показываю важные поля):

+----------------------+
|id|name |collective_id|
+----------------------+
|1 |dark |NULL         |
+----------------------+
|2 |thor |NULL         |
+----------------------+
|3 |vinky|NULL         |
+----------------------+

И внешняя таблица, связанная с пользователями пользователями.id (FK is contrats.user_id) именованные контракты:

-------------------------------------------------
|id|user_id|ts_from|ts_expire|type|collective_id|
-------------------------------------------------
|1 |1      |1000000|2000000  |1   |NULL         |
|2 |1      |1000001|2000001  |1   |NULL         |
|3 |1      |1000001|2000001  |3   |15           |
|4 |1      |1000002|2000002  |3   |8            |
|5 |2      |1000000|2200000  |2   |NULL         |

Я хочу получить следующий результат запроса:

-----------------------
|user_id|collective_id|
-----------------------
|1      |8            |
|2      |NULL         |
|3      |NULL         |

Результатом является объединение обеих таблиц, связанных споле contracts.user_id=users.id с LEFT JOIN, но с учетом того, что collective_id является самым последним полем в таблице contracts для поля ts_expire и с этим type = 3, это причина, по которой выбран collective_id для user_id 1 - это 8, а не 15, и другие пользователи не содержат collective_id, поскольку у них нет контракта с type = 3. Вы понимаете?

Последний вопрос, связанный с этой проблемой, состоит в том, что в моей таблице пользователей также есть поле collective_id, которое должно быть обновлено с этим значением, как должен быть запрос UPDATE, основанный на этих критериях, чтобыобновить поле users.collective_id?

Большое спасибо

Даниэль из Барселоны (эксперт по программированию php и не много сложных запросов mysql)

Я протестировал несколько запросов,но не сработало:

UPDATE `users` 
SET `collective_id` = (
    SELECT `collective_id` 
    FROM `contrats` 
    WHERE 
        `vigency` = 1 
        AND `type` = 3 
        AND `user_id` = 1 
    ORDER BY `ts_expire` DESC 
    LIMIT 1
) 
WHERE `users`.`id`=1;

Это сработало, но только для одного указанного пользователя, а не для всей таблицы пользователей.

UPDATE `users` u, contracts 
LEFT JOIN (
    SELECT `user_id`, `collective_id` 
    FROM `contratos` 
    WHERE 
        `users_id`= u.`id` 
        AND `vigency`= 1 
        AND `type` = 3
) contracts ON contracts.`user_id`=u.`id` 
SET `collective_id` = contracts.`collective_id` 
WHERE 1;

Это сработало неправильно, обновив весь users.collective_id с помощьюто же значение.

1 Ответ

1 голос
/ 31 октября 2019

Для запроса на выборку вы можете left join и выполнить фильтрацию с помощью коррелированного подзапроса:

select 
    u.user_id,
    c.collective_id
from users u
left join contrats c
    on  c.user_id = u.user_id
    and c.vigency = 1
    and c.type = 3
    and c.ts_expire = (
        select max(ts_expire)
        from contracts c1
        where 
            c1.user_id = c.user_id 
            and c1.vigency = c.vigency 
            and c1.type = c.type
    )

Ваш запрос на обновление уже почти готов, вам просто нужно сопоставить подзапрос свнешний запрос

update users u set collective_id = (
    select collective_id 
    from contrats c
    where 
        c.vigency = 1 
        and c.type = 3 
        and c.user_id = u.user_id
        order by c.ts_expire 
        desc limit 1
    )

Обратите внимание, что для него будет задано null записей, для которых подзапрос будет пустым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...