Mysql Tabelle Kopieren aber auf vorhandene Einträge achten

gine78

Grünschnabel
Hallo Toutorial.de,

so... nun habe ich mich auch mal angemeldet, ich verzweifle langsam...

Meine Situation:
Ich bekomme eine CSV Datei welche ich im Anschluß in eine mysql datenbank importiere, die Tabelle sieht dann so aus:
Tabelle1
Code:
|name|datum|art
diese ist gefüllt mit einem Monat Dienstplan, jedoch nur bezogen auf diese drei Einträge.

Nun habe ich eine zweite Tabelle in welche die Daten kopiert werden sollen, soweit kein Problem... bis zu dem Zeitpunkt wo schon Daten zu dem Namen und dem Datum in dieser Tabelle stehen. Ich kann in dieser Tabelle keine doppelten Einträge gebrauchen, da mir doppelte Einträge den kompletten Dienstplan zerkloppen.

Lange Rede kurzer Sinn:

Ich suche eine Möglichkeit die Tabelle1 in Tabelle2 zu kopieren, jedoch inclusiv der Überprüfung ob schon ein Datensatz zu dem Namen und dem Datum existiert, wenn schon einer existiert soll dieser nicht in die Tabelle2 kopiert werden.

Ich will das ganze gern direkt in mysql ausführen, ohne php... würde aber im Notfall auch php nutzen.

Hat jemand einen klitzekleinen Ansatz für mich?

Vielen lieben Dank,
Carsten
 
Einfach die entsprechenden Spalten UNIQUE oder PRIMARY_KEY makieren ... dann macht den Rest die DB selbst.
 
Hallo,

ja würde gehen... wenn... das ganze nicht so doof wäre wie es ist.

Ich habe in der Tabelle leider zum Datum mehrere einträge:

Z.B.:

|name|datum|art
|wxyz|2011-11-11|event
|abcd|2011-11-11|event
|lmno|2011-11-11|fbp
usw...

Ich kann also auf keine Spalte einen UNIQUE setzen.
 
Hmm ... ok .. das klingt einleuchtend. Sorry ... ich dachte du arbeitest mit dierektem Timestamp oder sowas.
Ob es jetzt aber etwas gibt das einen kompletten Datensatz prüft ? Ja gut ... ich könnt mir denken das das mit so nem kranken Query über 5 Ecken geht ... aber so bewandert bin ich dann doch leider nicht auf dem Gebiet das ich dir sowas zusammenbauen könnte.
 
@CPloy
Manache Leute sind einfach nur genial. Daran habe ich überhaupt nicht gedacht das du ja den Index über mehrere Spalten strecken kannst.

*boar man bin ich doof*
 
Ok,
Das klingt logisch, habe aber damit noch nicht gearbeitet.

D.h. Ich setze einen Index auf Name u. Datum, das löst mein Problem?
Ich setze den Index logischerweise auf die zieltabelle, kopiere meine quelltabelle rüber... MySQL ignoriert dann alle "Rows" welche die gleichen Werte haben wie die auf denen ich den Index gesetzt habe?

Also in meinem Beispiel wäre der Index auf dem namen und dem Datum. Da zu jedem Datum höchstens nur ein Datensatz existieren darf. Habe ich das soweit richtig verstanden?

Vielen lieben Dank!
 
@CPloy
Manache Leute sind einfach nur genial. Daran habe ich überhaupt nicht gedacht das du ja den Index über mehrere Spalten strecken kannst.

*boar man bin ich doof*

Übertreib mal nicht, jeder steht mal auf dem Schlauch ;-)

Ok,
D.h. Ich setze einen Index auf Name u. Datum, das löst mein Problem?
Ich setze den Index logischerweise auf die zieltabelle, kopiere meine quelltabelle rüber... MySQL ignoriert dann alle "Rows" welche die gleichen Werte haben wie die auf denen ich den Index gesetzt habe?

Also in meinem Beispiel wäre der Index auf dem namen und dem Datum. Da zu jedem Datum höchstens nur ein Datensatz existieren darf. Habe ich das soweit richtig verstanden?

Ja, das stimmt so weit. Du musst aber noch etwas beachten: MySQL wirft eine Fehlermeldung, sobald du einen doppelten Datensatz einfügen willst. Das kannst du aber verhindern.

Aber von vorne:

SQL:
create table test (a INT, b INT);

create unique index `mein_index` on test (a,b);

insert into test values (1,1), (1,2), (1,3);

Jetzt haben wir unsere Testtabelle, bei der die Kombination aus a und b eindeutig sein muss. Versuchen wir mal einen doppelten Datensatz UND einen neue einzufügen.


SQL:
insert into test values (1,1), (1,4);

ERROR 1062 (23000): Duplicate entry '1-1' for key 'mein_index'

select * from test;
+------+------+
| a    | b    |
+------+------+
|    1 |    1 |
|    1 |    2 |
|    1 |    3 |
+------+------+
3 rows in set (0.00 sec)

Keine der beiden wurde eingefügt!

Das kannst du aber explizit ändern (beachte das IGNORE schlüsselwort).

SQL:
insert ignore into test values (1,1), (1,4);

select * from test;
+------+------+
| a    | b    |
+------+------+
|    1 |    1 |
|    1 |    2 |
|    1 |    3 |
|    1 |    4 |
+------+------+
4 rows in set (0.00 sec)

Neben IGNORE kannst du auch noch was anderes machen.

SQL:
alter table test add c INT NOT NULL default 0;

select * from test;
+------+------+---+
| a    | b    | c |
+------+------+---+
|    1 |    1 | 0 |
|    1 |    2 | 0 |
|    1 |    3 | 0 |
|    1 |    4 | 0 |
+------+------+---+
4 rows in set (0.00 sec)

insert into test (a,b) values (1,1) on duplicate key update c=c+1;

select * from test;
+------+------+---+
| a    | b    | c |
+------+------+---+
|    1 |    1 | 1 |
|    1 |    2 | 0 |
|    1 |    3 | 0 |
|    1 |    4 | 0 |
+------+------+---+
4 rows in set (0.00 sec)


In dem Fall benutzen wir ON DUPLICATE KEY UPDATE, um zu zählen, wie oft versucht wurde, ein doppelten Key einzufügen. Du könntest damit auch z.B. ein timestamp updaten oder ähnliches.


Edit: In deinem Fall also:

SQL:
create table test2 (a INT, b INT);

insert into test2 values (1,1), (1,2), (5,6);

insert ignore into test (a,b) select a,b from test2;

select * from test;
+------+------+---+
| a    | b    | c |
+------+------+---+
|    1 |    1 | 1 |
|    1 |    2 | 0 |
|    1 |    3 | 0 |
|    1 |    4 | 0 |
|    5 |    6 | 0 |
+------+------+---+
5 rows in set (0.00 sec)
 
Zuletzt bearbeitet:
CPoly,

ich bin ehrlich gesagt ziemlich sprachlos! Ich benutze das Internet seit 1998, ich hab schon viele Foren gesehen bzw. erlebt... aber so eine TOP! Antwort auf eine Frage habe ich noch NIE bekommen. Herzlichen Dank******


Was mir hierbei ja besonders gefällt ist "ON DUPLICATE KEY UPDATE" - So kann ich auslesen welche datensätze nicht geschrieben wurden und diese nachträglich anzeigen lassen.

ICH werde berichten!

VIELEN DANK noch einmal******
 
Freut mich, dass ich helfen konnte. Ich schreib auch nicht immer so ausführliche Antworten, aber ich hatte gerade Lust das ganze schnell mal durch zuspielen.
 

Neue Beiträge

Zurück