根据序列

时间:2016-07-28 11:33:06

标签: mysql sql liquibase

我正在尝试使用具有特定条件的另一个表的列的OID更新(引用)一个表的列(oid)。

示例:

Customer Table :
------------------
CID  name   oid
-------------------
1  abc     null
2  abc     null
3  abc     null
4  xyz     null
--------------------

Order Table
--------------
OID  name
--------------
10   abc
11   abc
12   abc
13   xyz
--------------

输出应该是:

Customer Table :
------------------
CID  name   oid
-------------------
1    abc     10
2    abc     11
3    abc     12
4    xyz     13
--------------------

我试过以下

UPDATE customer as c, order as o
   SET c.oid = o.OID
   WHERE c.name = o.name;
-----------------------------
update customer INNER JOIN order on customer.name=Order.name
SET customer.oid=Order.OID
where customer.oid IS null;

但是客户表的更新如下

Customer Table :
------------------
CID  name   oid
-------------------
1    abc     10
2    abc     10
3    abc     10
4    xyz     13
--------------------

2 个答案:

答案 0 :(得分:2)

我们的想法是为Customer表和Order表中的每个条目分配一个行号。

因此,当在这两个表之间创建 inner join 时,您现在有两个条件(而之前它只是一个名称)。

一个条件是name,另一个条件是row_number

您可以使用此查询:

UPDATE Customer CT
INNER JOIN (
    SELECT
        customerTable.CID,
        orderTable.OID FROM 
        (
            SELECT
                *, 
                @rn1 := @rn1 + 1 AS row_number
            FROM
                Customer C
            CROSS JOIN (SELECT @rn1 := 0) var
            ORDER BY CID
        ) AS customerTable
    INNER JOIN (
        SELECT
            *, 
            @rn2 := @rn2 + 1 AS row_number
        FROM
            `Order` O
        CROSS JOIN (SELECT @rn2 := 0) var
        ORDER BY OID
    ) AS orderTable ON customerTable. NAME = orderTable. NAME
    AND customerTable.row_number = orderTable.row_number
) AS combinedTable ON CT.CID = combinedTable.CID
SET CT.oid = combinedTable.OID

注意:由于在匹配name上加入这两个表格不足以满足您的需求。这就是为什么除了匹配名称之外,还为每个行分配了一个row_number(在CustomerOrder表中。然后在匹配name上的这两个表之间进行内连接row number。因此,您要限制一个条目与另一个表中的其他条目多次连接。

TEST SCHEMA& DATA:

无法添加sql小提琴

DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
  `CID` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `oid` int(11) DEFAULT NULL,
  PRIMARY KEY (`CID`)
);
INSERT INTO `customer` VALUES ('1', 'abc', null);
INSERT INTO `customer` VALUES ('2', 'abc', null);
INSERT INTO `customer` VALUES ('3', 'abc', null);
INSERT INTO `customer` VALUES ('4', 'xyz', null);

DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
  `OID` int(11) NOT NULL,
  `name` varchar(100) NOT NULL
);
INSERT INTO `order` VALUES ('10', 'abc');
INSERT INTO `order` VALUES ('11', 'abc');
INSERT INTO `order` VALUES ('12', 'abc');
INSERT INTO `order` VALUES ('13', 'xyz');

现在看,Customer表格如何:

SELECT
*
FROM Customer;

<强>输出:

CID name  oid
1   abc   10
2   abc   11
3   abc   12
4   xyz   13

答案 1 :(得分:1)

这很复杂。您需要为每个值分配一个计数器变量 - 这在update语句中有点痛苦。但是这样的事情应该有效:

update customer c join
       (select c.*,
               (@rn := if(@n = name, @rn + 1,
                          if(@n := name, 1, 1)
                         )
               ) as rn
        from customer c cross join
             (select @n := '', @rn := 0) params
        order by name, cid
       ) cc
       on c.cid = cc.cid join
       (select o.*,
               (@rno := if(@no = name, @rno + 1,
                           if(@no := name, 1, 1)
                          )
               ) as rn
        from orders o cross join
             (select @no := ', @rno := 0) params
       ) o
       on c.name = o.name and c.rn = o.rn
    set c.oid = o.oid;