Avatar billede nemlig Professor
04. september 2023 - 15:42 Der er 9 kommentarer og
2 løsninger

Sammenlæg 2 x tabeller

Hejsa.
Jeg har en del databaser med samme tabel strukturer, som jeg over tid skal samle i én og samme database.
Derfor ser jeg lige nu på, hvordan jeg kan samle posterne fra 2 tabeller med samme struktur og med feltet `id` som primær nøgle.

Når jeg har løsningen, så er det forholdvis enkelt at loppe koden, så det også sker med de øvrige tabeller.
Umiddelbart havde jeg tænkt noget i retning af :

Insert into Database.table1 (*) SELECT (*) from Database2.table2;

Men jeg ser en udfordring i, at feltet `id` er primærnøgle og med AUTOINCREMENT.

Nogen forslag til løsning?

PS. Jeg programmerer mit konverteringsscript i PHP.
Avatar billede arne_v Ekspert
04. september 2023 - 15:58 #1
Hvis der ikker andre tabeller som bruger det id, så er det jo nemt at erstatte id for table2.

Enten med en SQL INSERT med alle fleter undtagen id felt.

Eller med PHP kode som henter en række fra table2 og indsætter i table1.

Er der andre tabeller som har en fremmednøgle til id i table2 så er det mere tricky fordi de skal også ændres. Så skal du igang med PHP kode og en oversættelse af id i de andre tabeller.
Avatar billede nemlig Professor
04. september 2023 - 16:21 #2
#1 `id`bruges alene til at identificere en post ved listeudtræk, opdatering og sletning. Så `id`bruges ikke af andre tabeller.
Man kan vel også bare slette feltet `id` i de 2 tabeller, sammenlægge dem, og derefter tilføje `id`feltet med AUTOINCREMENT. Vil posterne så ikke få tildelt et fortløbende `id`?
Eller mener du bare, at `id`-feltet fjernes i table2 og derefter indsætte alle poster i table1, hvorved de indsatte poster får tildelt et nyt `id`?
Avatar billede arne_v Ekspert
04. september 2023 - 16:47 #3
Hvis table 1 har autoincrement p id og du indsætter alle rækker alle felter undtagen id fra table2, så bør de få et nyt id tildelt.
Avatar billede arne_v Ekspert
04. september 2023 - 16:54 #4
mysql> CREATE TABLE x1 (
    ->    id INTEGER NOT NULL AUTO_INCREMENT,
    ->    v VARCHAR(32),
    ->    PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO x1(v) VALUES('A');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO x1(v) VALUES('B');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM x1;
+----+------+
| id | v    |
+----+------+
|  1 | A    |
|  2 | B    |
+----+------+
2 rows in set (0.00 sec)

mysql> CREATE TABLE x2 (
    ->    id INTEGER NOT NULL AUTO_INCREMENT,
    ->    v VARCHAR(32),
    ->    PRIMARY KEY(id)
    -> );
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO x2(v) VALUES('C');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO x2(v) VALUES('D');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM x2;
+----+------+
| id | v    |
+----+------+
|  1 | C    |
|  2 | D    |
+----+------+
2 rows in set (0.00 sec)

mysql> INSERT INTO x1(v) SELECT v FROM x2;
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM x1;
+----+------+
| id | v    |
+----+------+
|  1 | A    |
|  2 | B    |
|  3 | C    |
|  4 | D    |
+----+------+
4 rows in set (0.00 sec)

mysql> DROP TABLE x1;
Query OK, 0 rows affected (0.01 sec)

mysql> DROP TABLE x2;
Query OK, 0 rows affected (0.01 sec)
Avatar billede nemlig Professor
04. september 2023 - 17:37 #5
Tak Arne for godt input.
Jeg har 30 tabeller i samme database, og når jeg sammenlægger tabellerne fra database2 til tabellerne i database1 (den fortsættende), så vil jeg gerne forenkle opgaven. Også når jeg tænker på, at jeg har 70 databaser, som skal sammenlægges til én. Det er et projekt, som tager måneder, da der følger en del andet med.

Derfor laver jeg et PHP-script, som klarer det meste.
De 30 tabelnavne har jeg smidt i et array, som jeg lopper med noget kode, som skal indsætte poster fra tabel i DB2 til tabel  i DB1 - noget ala:
foreach ($tabel as $value) {
    mysqli_query($db,"INSERT INTO `".$dbname1."`.`".$value."` FROM `".$dbname2."`.`".$value."` ")or die (mysqli_error($db));
}

Jeg ved godt, at SQL-koden ikke er korrekt, men har du konkret input til koden.
Hvis det kan være løsningen, kan jeg godt fjerne feltet ´id`i tabellerne i DB2 (og evt. i DB1).
Her kan jeg jo bare smide denne kode i mit loop:
mysqli_query($db,"ALTER TABLE `".$dbname1."`.`".$value."` DROP `id` ")or die (mysqli_error($db)); 

Og jeg kan så til sidst i mit loop tilføje feltet `id`til tabel i DB1.

Hvis ovenstående kan være en løsning, hvad er den konkrete kode for at hente posterne i DB2.tabel og indsætte i DB1.tabel ?
Avatar billede arne_v Ekspert
04. september 2023 - 18:51 #6
Jeg kan ikke skrive al koden for dig.

Men jeg kan outline en algoritme:

function process_table($tblnam) {
    $fields = get_all_fields_except_id_in_table($tablnam);
    $fldlst = implode(',', $fields);
    $sqlstr = "INSERT INTO $tblnam VALUES($fldlst) SELECT $fldlist FROM $tblnam");
    echo "$sqlstr\r\n";
    execute_sql($sqlstr);
}

foreach($tbllist as $tblnam) {
    process_table($tblnam);
}
Avatar billede nemlig Professor
04. september 2023 - 20:44 #7
Hej Arne. Det var bestemt ikke meningen, at du skulle skrive koden for mig. Beklager at jeg ikke har udtrykt det tydeligt nok.
Jeg er ikke skarp på MySQL og har ikke styr på, om man ved en enkelt kodelinje, kunne kopiere alle poster fra tabel2 til tabel1.
Derfor jeg dvæler en del omkring:
Insert into table1 from table2

Men tak for dit input til programkode. Det kigger jeg nærmere på.
Avatar billede arne_v Ekspert
04. september 2023 - 20:57 #8
INSERT INTO x1(v) SELECT v FROM x2;

kopierede alle rækker fra x2 til x1.

Du skal have en SQL per tabel.

Og lidt af tricket er at få lavet en liste med felter. Mit eksempel havde kun et felt udover id nemlig v.

Var der v1, v2 og v3 skulle SQL have været:

INSERT INTO x1(v1,v2,v3) SELECT v1,v2,v3 FROM x2;

og meget af tricket er at få lavet den felt liste,
Avatar billede arne_v Ekspert
04. september 2023 - 20:59 #9
Hint:

$getfieldssql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = $tblnam";
Avatar billede nemlig Professor
04. september 2023 - 21:15 #10
Tjek :). Jeg havde håbet på, at det ikke var nødvendigt med feltnavnene, så det bliver lidt mere udfordrende. Tak for dit hint - nu er jeg klædt rigtigt godt på til løsningen.

Tak for dine super input :).
Avatar billede nemlig Professor
05. september 2023 - 22:14 #11
Til Arne: Jeg vil lige sige endnu engang kæmpe stor tak for dine gode input.
Jeg har nu lavet løsningen med udgangspunkt i dine forslag, herunder dit hint i #9.
Med ét lille php-script sammenlægger jeg nu 30 tabeller på få sekunder - det er ret fedt, at det nu spiller. Så venlige og gode tanker herfra til dig :):):)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester