2016-06-19 15 views
0

Ich bin auf der Suche nach einer Update-Anweisung, werden Gruppenausdrücke von Sprache in der folgenden TabelleMysql: Update mit ausgewähltem und lokalen Variable

CREATE TABLE _tempTerms(
     ID int(8) unsigned NOT NULL AUTO_INCREMENT, 
     TTC_ART_ID mediumint(8) unsigned, 
     TTC_TYP_ID mediumint(8) unsigned, 
     Name varchar(200), 
     Value varchar(200), 
     ID_Lang tinyint(3) unsigned, 
     Sequence smallint unsigned, 
     Group_ID int(8) unsigned DEFAULT 0, 
     PRIMARY KEY(TTC_ART_ID, TTC_TYP_ID, Name, Value), 
     UNIQUE KEY(ID) 
    ); 

Alle Daten außer Group_ID in die Tabelle eingefügt wird. Ich muss die Tabelle aktualisieren, damit ich automatisch neue Group_IDs erzeuge und die Group_ID für alle Datensätze mit derselben Kombination von TTC_ART_ID, TTC_TYP_ID und Sequence die gleiche Group_ID erhalten. Ich glaube, ich eine Variable benötigen Sie den aktuellen Wert für Group_ID zu speichern und so weit experimentierte ich mit

SET @group_id:=1; 
UPDATE _tempTerms 
SET Group_ID = (@group_id := @group_id + 1); 

, die gerade ein neues group_id zu jedem neuen Datensatz gibt. Ich glaube, ich brauche irgendwo eine SELECT-Anweisung, um zu überprüfen, ob eine group_id bereits vergeben ist, aber ich bin verwirrt darüber, wie ich vorgehe.

Danke

+0

übrigens heißen diese [Benutzervariablen] (http://dev.mysql.com/doc/refman/5.7/en/user-variables.html). Nicht [Lokale Variablen] (http://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html). – Drew

+0

so wird es ein Update mit einem Join-Muster sein. Der Join kann sich auf eine abgeleitete Tabelle beziehen, die über eine Variable eine "Gruppe nach" oder "unterscheidbar" und einen inkrementierten Rang oder ein erhöhtes Ranking aufweist. Diese Art von Ding. – Drew

+0

@Drew Vielen Dank für Ihre Korrektur und Anregung. –

Antwort

1

Schema:

create database xGrpId; -- create a test db 
use xGrpId; -- use it 

CREATE TABLE _tempTerms(
     ID int(8) unsigned NOT NULL AUTO_INCREMENT, 
     TTC_ART_ID mediumint(8) unsigned, 
     TTC_TYP_ID mediumint(8) unsigned, 
     Name varchar(200), 
     Value varchar(200), 
     ID_Lang tinyint(3) unsigned, 
     Sequence smallint unsigned, 
     Group_ID int(8) unsigned DEFAULT 0, 
     PRIMARY KEY(TTC_ART_ID, TTC_TYP_ID, Name, Value), 
     UNIQUE KEY(ID) 
    ); 

-- truncate table _tempTerms; 
insert _tempTerms(TTC_ART_ID,TTC_TYP_ID,Name,Value,ID_Lang,Sequence) values 
(1,2,'n','v1',66,4), 
(1,1,'n','v2',66,4), 
(1,1,'n','v3',66,3), 
(1,1,'n','v4',66,4), 
(1,1,'n','v5',66,4), 
(1,1,'n','v6',66,3), 
(2,1,'n','v7',66,4), 
(1,2,'n','v8',66,4); 

Sehen Sie sie:

select * from _tempTerms order by id; 
select distinct TTC_ART_ID,TTC_TYP_ID,Sequence from _tempTerms; 
-- 4 rows 

- update _tempTerms gesetzt Group_ID = 0; - klar vor der Prüfung

Die Abfrage:

update _tempTerms t 
join 
( select TTC_ART_ID,TTC_TYP_ID,Sequence,@rn:[email protected]+1 as rownum 
    from 
    ( select distinct TTC_ART_ID,TTC_TYP_ID,Sequence 
     from _tempTerms 
     -- put your `order by` here if needed 
     order by TTC_ART_ID,TTC_TYP_ID,Sequence 
    ) d1 
    cross join (select @rn:=0) as xParams 
) d2 
on d2.TTC_ART_ID=t.TTC_ART_ID and d2.TTC_TYP_ID=t.TTC_TYP_ID and d2.Sequence=t.Sequence 
set t.Group_ID=d2.rownum; 

Ergebnisse:

select * from _tempTerms order by TTC_ART_ID,TTC_TYP_ID,Sequence; 

+----+------------+------------+------+-------+---------+----------+----------+ 
| ID | TTC_ART_ID | TTC_TYP_ID | Name | Value | ID_Lang | Sequence | Group_ID | 
+----+------------+------------+------+-------+---------+----------+----------+ 
| 3 |   1 |   1 | n | v3 |  66 |  3 |  1 | 
| 6 |   1 |   1 | n | v6 |  66 |  3 |  1 | 

| 2 |   1 |   1 | n | v2 |  66 |  4 |  2 | 
| 4 |   1 |   1 | n | v4 |  66 |  4 |  2 | 
| 5 |   1 |   1 | n | v5 |  66 |  4 |  2 | 

| 1 |   1 |   2 | n | v1 |  66 |  4 |  3 | 
| 8 |   1 |   2 | n | v8 |  66 |  4 |  3 | 

| 7 |   2 |   1 | n | v7 |  66 |  4 |  4 | 
+----+------------+------------+------+-------+---------+----------+----------+ 

Cleanup:

drop database xGrpId; 

d1, d2 und xParams sind abgeleitete Tabellen. Jede abgeleitete Tabelle benötigt einen Namen. Der Zweck von xParams und cross join ist lediglich, eine Variable einzufügen, um die Zeilennummer zu initialisieren. Dies liegt daran, dass mysql keine CTE-Funktionalität in anderen RDBMS hat. Überdenken Sie also nicht die cross join. Es ist wie gesagt LET i=0.

+0

Vielen Dank für diese ausgezeichnete Antwort! Nur noch eine Sache: Meine Tabelle wird ungefähr 100 Millionen Zeilen umfassen, wenn ich dies ausführe. Vielleicht haben Sie Tipps zu Indizes, um die Leistung zu verbessern? Mit 150 tausend Reihen dauerte es ungefähr 13 Sekunden. –

+0

Versuchen Sie es mit 3 bis 5 Millionen. Vielleicht können wir das distinct in eine 'group by' ändern, nachdem die distinkte Linie in ein Aggregat umgewandelt wurde. Aber wenn es eine Wegwerfroutine ist und es gut funktioniert, warum sollte man es überarbeiten? Gib mir Bescheid. Beachten Sie, dass manche Leute in Abfragen eine Gruppe verwenden, die nicht einmal Aggregate als Trick haben. Aggregatfunktionen wie Summe, Durchschnitt, Anzahl ... – Drew