2016-07-28 4 views
2

Ich versuche, eine Spalte (oid) einer Tabelle mit OID einer anderen Tabellenspalte unter bestimmten Bedingungen zu aktualisieren (zu referenzieren).Referenzierungsspalte in Abhängigkeit von IDs einer anderen Spalte in der Sequenz

Beispiel:

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 
-------------- 

Ouput sollte sein:

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

ich versucht habe, die folgende

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; 

Aber der Kundentabelle aktualisiert wird als

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

Antwort

2

Die Idee ist, eine Zeilennummer zu jedem der Einträge in Customer Tabelle und Order Tabelle zuzuordnen.

Wenn also ein inner join zwischen diesen beiden Tabellen zu machen, haben Sie zwei jetzt Bedingungen (während zuvor war es einer das heißt nur Name).

Eine Bedingung ist name und eine weitere ist die row_number

Sie mit dieser Abfrage gehen:

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 

Hinweis: Da diese beiden Tabellen verknüpft name auf passende für nicht ausreichend ist, was sind Du suchst nach. Deshalb vergeben Sie neben dem passenden Namen eine Zeilennummer für jede der Zeilen (beide in Customer und Order Tabelle. Dann machen Sie einen inneren Join zwischen diesen beiden Tabellen auf übereinstimmenden name und row number. So beschränken Sie einen Eintrag, der mehrfach mit anderen Einträgen verbunden wird aus einer anderen Tabelle


TEST SCHEMA & DATA.

kann nicht eine sQL-Geige

hinzufügen
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'); 

Siehe, wie sieht die Customer Tabelle wie folgt aussehen:

SELECT 
* 
FROM Customer; 

Ausgang:

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

Danke, ich werde das jetzt ausprobieren. – Ravikumar

+0

Bitte überprüfen Sie die Abfrage zuerst auf die angegebenen Daten, die ich gerade gepostet habe. @Ravikumar – 1000111

+1

Danke, es hat funktioniert. Schöne Erklärung – Ravikumar

1

Dies ist sehr kompliziert zu tun. Sie müssen jedem Wert eine Zählervariable zuweisen - was in einer update-Anweisung ein wenig schmerzhaft ist. Aber so etwas wie dies funktionieren soll:

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; 
+0

Danke, werde ich das versuchen, aber können Sie bitte kurz erklären, was diese Abfrage macht? Sieht kompliziert aus – Ravikumar

+0

@Ravikumar. . . Es zählt die "name" -Werte in jeder Tabelle auf, so dass der enumerierte Wert ("counter") für den Join verwendet werden kann. –

+0

Vielen Dank für die Antwort, aber ich kann nur eine Antwort auswählen, so eine Upvote gegeben. – Ravikumar

Verwandte Themen