Как обновить записи, когда подзапрос возвращает более 1 строки - PullRequest
0 голосов
/ 13 июня 2019

Например, мне нужно автоматически / случайно назначить «нового» Лидера, чтобы вести учеников (выберите только 1 ученика из каждого типа), и ежедневно предположить, что в таблице Лидеров всего 10 лидеров.

Но я получаю неправильный результат, используя приведенный ниже запрос, он в первый раз обновит всех учащихся с одинаковым идентификатором лидера.

UPDATE students 
   SET student_status = 'assigned'
     , leader_id = 'abc' 
 WHERE student_id IN 
         ( SELECT student_id 
             FROM  
                ( SELECT * 
                    FROM students
                ) s 
            WHERE student_status = 'New'  
            GROUP
               BY type_id)

Мой ожидаемый результат похож на приведенный ниже запрос, но я не хочу запускать другую логику для генерации случайного идентификатора student_id:

UPDATE students
SET student_status='assigned', leader_id='abc' 
WHERE student_id IN ('T0123','S0222','T7777','S8888')


student_id | type_id | leader_id | student_status
-----------+---------+-----------+---------------
T0121      | Type 1  |    xyz    | assigned
T0122      | Type 1  |           | new
T0123      | Type 1  |           | new
S0221      | Type 2  |           | new
S0222      | Type 2  |           | new
S0223      | Type 2  |    xyz    | assigned
T7777      | Type 3  |           | new
T7779      | Type 3  |    xyz    | assigned
S8888      | Type 4  |    xyz    | assigned
S8887      | Type 4  |           | new
S8886      | Type 4  |           | new

Ответы [ 3 ]

0 голосов
/ 13 июня 2019

Это должно работать.Это будет выбирать 1 нового ученика каждый раз из каждого типа и обновлять статус и идентификатор лидера соответственно.

UPDATE students 
SET student_status = 'assigned'
, leader_id = 'abc' 
WHERE student_id IN (
    SELECT student_id FROM (
        SELECT c.student_id, c.student_status, c.type_id
        FROM students C 
        WHERE c.student_status = 'New'
        ORDER BY RAND()
    ) AS shuffled_items
    GROUP BY type_id
)
0 голосов
/ 13 июня 2019

Используйте RAND (), чтобы получить случайный leader_id между 1 и максимальным leader_id, и подзапрос, используя ROW_NUMBER и OVER, чтобы получить случайный student_id для каждого типа для обновления

UPDATE students s
JOIN (SELECT type_id, student_id, ROW_NUMBER() OVER (PARTITION BY type_id ORDER BY RAND()) rnum
      FROM students 
      WHERE status = 'new') r ON r.type_id = s.type_id AND
                                 r.student_id = s.student_id AND 
                                 rnum = 1
SET leader_id = (SELECT CEIL(RAND() * MAX(leader_id)) FROM leaders),
    status = 'assigned'
WHERE status = 'new'
0 голосов
/ 13 июня 2019

Для MySQL:

UPDATE students 
SET student_status='assigned', leader_id='abc' 
WHERE student_id IN (
    SELECT student_id FROM  (
         SELECT * FROM students)  AS s 
    WHERE student_status ='New'  GROUP BY type_id ORDER BY RAND()
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...