简体   繁体   English

从另一个表 MySQL 更新行设置唯一值

[英]Update rows set uniqe values from another table MySQL

I have two tables for example.例如,我有两张桌子。 First contains generated serials for details.首先包含生成的连续剧以获取详细信息。 The second contains produced datails.第二个包含生产的数据。 I need to insert unique serial numbers to the second.我需要在第二个中插入唯一的序列号。

T1 T1

t1.ID t1.ID t1.OBJ_TYPE t1.OBJ_TYPE t1.OBJ_SERIAL t1.OBJ_SERIAL
1 1 5 5 DRW157001 DRW157001
2 2 5 5 DRW157002 DRW157002
3 3 5 5 DRW157003 DRW157003
4 4 5 5 DRW157004 DRW157004
5 5 5 5 DRW157005 DRW157005
6 6 5 5 DRW157006 DRW157006

T2 T2

t2.ID t2.ID t2.DETAIL_TYPE t2.DETAIL_TYPE t2.DETAIL_SERIAL t2.DETAIL_SERIAL
1 1 5 5 DRW157001 DRW157001
2 2 5 5 DRW157005 DRW157005
3 3 5 5 NULL NULL
4 4 5 5 NULL NULL
5 5 5 5 NULL NULL
6 6 5 5 NULL NULL

Is it possible to to make like this after update?更新后可以这样吗?

Result结果

t2.ID t2.ID t2.DETAIL_TYPE t2.DETAIL_TYPE t2.DETAIL_SERIAL t2.DETAIL_SERIAL
1 1 5 5 DRW157001 DRW157001
2 2 5 5 DRW157005 DRW157005
3 3 5 5 DRW157002 DRW157002
4 4 5 5 DRW157003 DRW157003
5 5 5 5 DRW157004 DRW157004
6 6 5 5 DRW157006 DRW157006

SQL query SQL查询

UPDATE t2, t1 SET t2.DETAIL_SERIAL = (SELECT t1.OBJ_SERIAL FROM t1 LIMIT 1 ) WHERE t1.OBJ_TYPE = t2.DETAIL_TYPE

Yes, It is possible using JOIN in UPDATE as follows:是的,可以在UPDATE中使用JOIN ,如下所示:

UPDATE t2 
 INNER JOIN 
(SELECT T2ID, OBJ_SERIAL 
   FROM (SELECT T1.*, T2.ID T2ID, 
                ROW_NUMBER() OVER (ORDER BY T1.ID) AS T1RN,
                ROW_NUMBER() OVER (ORDER BY T2.ID) AS T2RN
           FROM T1 JOIN T2 ON T1.OBJ_TYPE = T2.DETAIL_TYPE
          WHERE T2.DETAIL_SERIAL IS NULL
            AND NOT EXISTS 
                (SELECT 1 FROM T2 T22 
                  WHERE T1.OBJ_TYPE = T22.DETAIL_TYPE
                    AND T22.DETAIL_SERIAL = T1.OBJ_SERIAL 
                 )
        ) T 
  WHERE T1RN = T2RN) T
 SET T2.DETAIL_SERIAL = T.OBJ_SERIAL 
 WHERE T2.ID = T.T2ID

Now i have that code and it's works for me.现在我有了那个代码,它对我有用。

SET @i := 0;
SET @j := 0;

UPDATE t2 DST LEFT JOIN 
(
    SELECT TD1.RNT1, TD1.OBJ_SERIAL, TD2.IDX, TD2.RNT2, TD2.DETAIL_SERIAL FROM 
    (
        SELECT @i := @i + 1 AS RNT1, TSRC1.OBJ_SERIAL FROM t1 TSRC1 WHERE NOT EXISTS ( SELECT 1 FROM t2 TSH1 WHERE TSRC1.OBJ_SERIAL = TSH1.DETAIL_SERIAL AND )
    ) TD1 
    LEFT JOIN 
    (
        SELECT @j := @j + 1 AS RNT2, TSRC2.ID IDX, TSRC2.DETAIL_SERIAL FROM t2 TSRC2 WHERE NOT EXISTS (SELECT 1 FROM t1 TSH2 WHERE TSRC2.DETAIL_SERIAL = TSH2.OBJ_SERIAL) AND TSRC2.DETAIL_SERIAL IS NULL
    ) TD2 
    ON TD1.RNT1 = TD2.RNT2 AND TD1.OBJ_TYPE = TD2.DETAIL_TYPE
) TD3 
ON DST.ID = TD3.IDX 
SET DST.DETAIL_SERIAL = TD3.OBJ_SERIAL
WHERE TD3.IDX IS NOT NULL;

Is there a better way?有没有更好的办法?

This is complicated.这是复杂的。 The idea is to do the following:想法是执行以下操作:

  1. Enumerate the rows in t2 where detail_serial is NULL .枚举t2detail_serialNULL的行。
  2. Enumerate the rows in t1 where obj_serial is not being used in t2 .枚举t1中未在t2中使用obj_serial的行。
  3. Join together for the update .一起加入update

What makes this a bit more complicated, is that (1) requires an additional join (to tt2 in the below query):使这更复杂的是,(1)需要一个额外的join (到下面查询中的tt2 ):

update t2 join
       (select t2.*,
               row_number() over (order by t2.id) as seqnum
        from t2
        where t2.DETAIL_SERIAL is null
       ) tt2
       on t2.id = tt2.id join
       (select t1.*,
               row_number() over (order by t1.id) as seqnum
        from t1
        where not exists (select 1
                          from t2
                          where t2.DETAIL_SERIAL = t1.OBJ_SERIAL
                         )
       ) t1
       on t1.seqnum = tt2.seqnum
    set t2.DETAIL_SERIAL = t1.OBJ_SERIAL;

I'm not quite sure where obj_type fits in. However, if it also needs to match, then include it in the not exists subquery and in the final join.我不太确定obj_type适合的位置。但是,如果它也需要匹配,则将其包含在not exists的子查询和最终连接中。 Or perhaps you just want to filter on the value.或者,也许您只是想过滤该值。

Here is a db<>fiddle. 是一个 db<>fiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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