jens1985
Goto Top

DB doppelte Einträge löschen nur die mit dem älteren Datum (spalte)

Hi,

ich habe mal wieder ein Problem.

Ich möchte in meiner Datenbank alle doppelten Einträge löschen aber nur die mit den älteren Datum.

Beispiel Auszug aus der Datenbank wie sie jetzt noch aussieht.

CharacterName CorporationName AllianceName KillID killTime shipTypeID characterID allianceID corporationID typiID
00soimulalcorian00 Haita de lupi ROMANIAN-LEGION 16177296 2014-12-29 20:01:00 23919 1830435815 557004256 1407651808 Aeon
00soimulalcorian00 Haita de lupi ROMANIAN-LEGION 16177243 2012-12-29 19:59:00 23919 1830435815 557004256 1407651808 Aeon
00soimulalcorian00 Haita de lupi ROMANIAN-LEGION 16177215 2010-12-29 19:57:00 23919 1830435815 557004256 1407651808 Aeon
Kyara Stone Sniggerdly Pandemic Legion 36691924 2014-02-11 20:41:00 23919 941424803 386292982 828800677 Nyx
Kyara Stone Sniggerdly Pandemic Legion 36691920 2013-02-11 20:41:00 23919 941424803 386292982 828800677 Nyx
Kyara Stone Sniggerdly Pandemic Legion 36691915 2012-02-11 20:41:00 23919 941424803 386292982 828800677 Nyx

So hätte ich es gerne

CharacterName CorporationName AllianceName KillID killTime shipTypeID characterID allianceID corporationID typiID
00soimulalcorian00 Haita de lupi ROMANIAN-LEGION 16177296 2014-12-29 20:01:00 23919 1830435815 557004256 1407651808 Aeon
Kyara Stone Sniggerdly Pandemic Legion 36691924 2014-02-11 20:41:00 23919 941424803 386292982 828800677 Nyx


Mein momentanes Script löscht alle komplett gleichen Einträge von CharacterName bis typeID und sieht so aus.
Auszug aus meiner .php Datei
<code type="php>
$createTab = "CREATE TABLE `table_NEU`
(

`characterName` VARCHAR( 255 ) NULL,
`corporationName` VARCHAR( 255 ) NULL,
`allianceName` VARCHAR( 255 ) NULL,
`KillID` VARCHAR( 255 ) NULL,
`killTime` VARCHAR( 255 ) NOT NULL,
`shipTypeID` VARCHAR( 255 ) NULL,
`characterID` VARCHAR( 255 ) NULL,
`allianceID` VARCHAR( 255 ) NULL,
`corporationID` VARCHAR( 255 ) NULL

);";
mysqli_query($db_link, $createTab);

$insertData = "INSERT INTO table_NEU SELECT DISTINCT * FROM table;";
mysqli_query($db_link, $insertData);

mysqli_query($db_link, "DROP TABLE table;");
mysqli_query($db_link, "RENAME TABLE table_NEU TO table;");


Kann mir da einer weiterhelfen.

Danke
Jens

Content-Key: 229662

Url: https://administrator.de/contentid/229662

Printed on: April 19, 2024 at 20:04 o'clock

Member: Clijsters
Clijsters Feb 13, 2014 updated at 22:17:32 (UTC)
Goto Top
Hallo Jens,

nichts leichter als das:
CREATE TABLE table_temp AS
SELECT * FROM table ORDER by killTime GROUP BY CharacterName;

DROP TABLE table;
RENAME TABLE table_temp TO table;

Es gibt noch unzählige weitere Methoden mit unzählig verschiedenen Eigenschaften. Hier hilft Google eigentlich sehr gut weiter.


Beste Grüße
Dominique
Member: Jens1985
Jens1985 Feb 13, 2014 updated at 22:36:40 (UTC)
Goto Top
Hi

ich bekomme jetzt folgendes:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY characterName' at line 2

Jens
Member: Clijsters
Solution Clijsters Feb 14, 2014 updated at 20:49:51 (UTC)
Goto Top
Hi
Tatsache, habe es gerade selber getestet. Das hätte ich auch vorher machen können...

Hier gibt's was zu dieser Kombination:
Stackoverflow - MySQL Order By before Group By

Es sollte aber wie bereits erwähnt bereits einiges geben: Siehe hier

Dominique
Member: Jens1985
Jens1985 Feb 14, 2014 at 00:28:45 (UTC)
Goto Top
Hi

habe bei Stackoverflow etwas gefunden was bis jetzt geklappt hat.

CREATE TABLE table_temp AS
SELECT t.* FROM (SELECT * FROM table ORDER BY killTime DESC) t GROUP BY characterName;

Ich schaue mir noch mal meine DB richtig an ob es auch das Ergebnis ist was ich gerne hätte.

Jens
Member: Biber
Biber Feb 14, 2014 at 11:44:57 (UTC)
Goto Top
Moin Jens1985,

wenn ich dein Beispiel richtig interpretiere, dann brauchst du weder eine implizit angelegte Temp-Tabelle noch diese Umkopiererei.

Mit diesem Statement...
select a.*
from
   table a
where 
   a.killtime <
     (select max(killtime) from table b
      where b.characterName = a.characterName
      and  b.corporationName = a.corporationName
      and  b.allianceName = a.allianceName
      and  b.shipTypeID = a.shipTypeID
      and  b.characterID = a.characterID
      and  b.allianceID = a.allianceID
      and  b.corporationID = a.corporationID
      and  b.typID = a.typID
               ) ;
sollten dir alle "älteren" doppelten Datensätze angezeigt werden
Und wenn du das " Select a.* from Table a" in ein "delete from table a" änderst, dann werden sie gelöscht.

Anmerkungen:
- natürlich ungetestet.
- die KillID habe ich natürlich rausgelassen aus der WHERE-Clause
- dafür habe ich das von dir nicht geprüfte "typID" mit reingenommen - falls es für deine "Duplikatsprüfung" wirklich nicht relevant ist, dann streich es wieder.
- statt des Vergleichs "a.killtime< max(b.killtime)" ginge vemutlich auch ein "a.killID< max(b.killId)", da diese ansonsten nutzlose KillID vermutlich so eine depperte Auto-ID ist, die bei jeder frischen Datensatz-Anlage (also abhängig von der Killtime) hochzählt.
- deine Tabelle sieht nicht so richtig doll normalisiert aus, sondern eher wie das Ergebnis eines Joins über 4 Tabellen. Brauchst du wirklich so viele redundante Felder, also "allianceID" UND "allianceName" und "xyID" UND "xyName" ?

Grüße
Biber
Member: Jens1985
Jens1985 Feb 14, 2014 at 20:49:45 (UTC)
Goto Top
Hi Biber

werde das von dir mal testen.

Zitat von @Biber:

- statt des Vergleichs "a.killtime< max(b.killtime)" ginge vemutlich auch ein "a.killID< max(b.killId)",
da diese ansonsten nutzlose KillID vermutlich so eine depperte Auto-ID ist, die bei jeder frischen Datensatz-Anlage (also
abhängig von der Killtime) hochzählt.
bezüglich der killID: Diese Id kann fortlaufend sein d.h. wird auf der seite von der ich meine daten beziehe etwas per hand eingetragen bekommt die ID in derer Datenbank ein "-" (minus) davor gesetzt. Wird es aber mittels eines API in die Datenbank geschrieben entsteht keine "-" (minus).

- deine Tabelle sieht nicht so richtig doll normalisiert aus, sondern eher wie das Ergebnis eines Joins über 4 Tabellen.
Brauchst du wirklich so viele redundante Felder, also "allianceID" UND "allianceName" und "xyID" UND
"xyName" ?
Da ich es nur als freizeitbeschäftigung mache, habe ich nicht sehr viel kenntnis in Sachen php, mysql usw. Was ich gelernt habe kann ich umsetzten, was ich nicht weis google ich bis ich was finde. Habe ich nichts gefunden frage ich hier.
Die ID's und Name brauche ich um ein href auf anderen seite zuerstellen. Manche seiten arbeiten mit z.b. (allianceName Pandemic Legion) Pandemic_Legion oder Pandemic+Legion. Damit ich das umgehe verwende ich die ID's. Ob CharacterName, CorporationName oder AllianceName die dazu gehöhrenen ID's sind immer gleich.

Danke für eure Hilfe
Jens