PHP Forum

PHP Forum (http://www.selfphp.de/forum/index.php)
-   MySQL/MySQLi (http://www.selfphp.de/forum/forumdisplay.php?f=22)
-   -   Duplikate löschen (http://www.selfphp.de/forum/showthread.php?t=26106)

Peter69 18.02.2018 12:25:15

Duplikate löschen
 
Guten Tag,

vielen Dank vorab für alle Tips.
Ich habe folgendes Problem:

Ich habe eine Tabelle

id |pos_id |pos |edit_time
1 |1 |1 |1518862618
2 |2 |2 |1518862618
3 |3 |3 |1518862618
4 |1 |1 |1518862518
5 |2 |2 |1518862518
6 |3 |5 |1518862518
7 |1 |1 |1518862718
8 |2 |2 |1518862718
9 |3 |1 |1518862718


pos_id ist die Referenz auf eine andere Tabelle
pos ist die aktuelle Position des Eintrages
edit_time ist der Unix Timestamp der Einragung

Dahinter verbirgt sich eine Tabelle, die durch Änderung des Wertes in pos umsortiert werden kann.
Ich möcht nun loggen, wie Werte umsortiert wurden.
Was ich gerne ereichen würde ist, den letzten Eintrag zur einer pos_id löschen, wenn sich der Wert in pos beim vorletzen Eintrag nicht geändert hat /je pos_id).

Um bei meiner Tabelle zu bleiben, sollte diese also nach der Aktion wie folgt aussehen:

id |pos_id |pos |edit_time
3 |3 |3 |1518862618
6 |3 |5 |1518862518
9 |3 |1 |1518862718

Man sieht also, dass der Datensatz "3" insgesamt 3 x geändert wurde.


Vielen Dank für einen Tip hierzu

LG

Peter

vt1816 18.02.2018 15:30:25

AW: Duplikate löschen
 
Hallo und willkommen hier im Forum.

Kann Dein Wunsch/Problem mit der jetzigen Beschreibung und den Beispielen noch nicht nachvollziehen. So wie Du es beschreibst, sollten doch mehr Datensätze übrig bleiben. Oder bezieht sich Dein gewünschtes Ergebnis nur auf pos_id = 3? Was ist mit pos_id = 1 bzw. 2?

Von wieviel Datensätzen sprechen wir hier?
Wie oft soll das durchgeführt werden?
Wie/wodurch werden die Datensätze angefügt?
Kann beim Anfügen schon auf Duplikat geprüft werden?
Wird eine pos_id gleichzeitig von mehreren Usern geändert/umsortiert?

Peter69 19.02.2018 08:56:20

AW: Duplikate löschen
 
Guten Morgen,

vielen Dank für Deine Hilfe und die freundliche Begrüßung.

Ich habe eine Tabelle mit ca. 250 Datensätzen.
Diese Tabelle ist das Ergebnis einer Selektion auf eine Tabelle mit ca. 15.000 Datensätzen.

Das Skript an dem ich gerade arbeite erlaubt dem Benutzer, die 250 Datensätze umzusortieren.
Es wird immer nur ein Benutzer zeitgleich Datensätze umsortieren.
Mein Skript geht aktuell her und macht nach einer Änderung ein Update auf von "pos"

PHP-Code:

if($action == "updateCustomerPos")

  
$counter 1;
  foreach (
$updRecArray as $recordIDValue
  {
    
$q_update $db->query("UPDATE Kunden SET pos = " $counter " WHERE id = " $recordIDValue);
    
$counter++; 
  }
  echo 
'Position gespeichert';


Soweit alles bestens.
Jetzt kam der Wunsch auf zu wissen, welcher Benutzer einen Datensatz verschoben hat.
Daher habe ich mir nachdem Update einen Insertbefehl eingebaut.

PHP-Code:

$q_history $db->query("INSERT INTO otrsplan_history (pos_id, pos, edit_by, edit_time) VALUES ('" $recordIDValue "','" $counter "','" $benutzer "','" $timestamp "')"); 

Dieser erzeugt meinen Log.

Das Problem ist nun:
Bei jeder Änderung schreibt der Insert Befehl 250 Zeilen in die Datenbank.
Auch dann, wenn isch eigentlich gar nix ändert.

Bsp: ich schiebe Pos 2 an Pos 1

Dann schreibt der Insert Befehl 250 Datensätze aber nur bei den ersten beiden hat sich die Position um Vergleich zum letzen Eintrag geändert.
248 Datensätze sind sinnfrei für das Logging.

Ich würde jetzt gerne hergehen und die sinnfreien Daten löschen.

PHP-Code:

Delet from otrsplan_history where "pos je pos_id mit MAX(timestamp) = "pos je pos_id mit MAX(timestamp)-

Das ganze würde ich dann direkt nach dem Insert durchführen.

Sollte mein Ansatz an sich falsch sein, bitte ich um Nachsicht...

Vielen Dank und LG

Peter

sysop 19.02.2018 10:24:27

AW: Duplikate löschen
 
Der timestamp ist vollkommen für die Katz, weil überall das selbe Datum steht.

Wieso gehst du denn alle Daten durch? Das entscheidest du doch bei deinem Sortierscript, wie immer du auch die beiden Datensätze markierst, die verschoben werden sollen.
Den Timestamp nur bei den verschobenen Daten aktualisieren und schon lasen sich die Daten nach dem letzten Sortierdatum gruppieren.

Zitat:

id |pos_id |pos |edit_time
1 |1|1 |1518862618
2 |2 |2 |1518862618
4 |1 |1 |1518862518
5 |2 |2 |1518862518
.
.
Die Daten sind bis auf die id (erste Spalte) vollkommen identisch, damit wäre das Design deiner Datenbank in meinen Augen falsch. Normalisieren wäre da das Zauberwort.
Da pos_id ein Fremdschlüssel ist, dürfte nach meiner Auffassung jede pos_id nur einmal in der Tabelle vorkommen.

Daher würde ich hier einen zusammengesetzten primary-Key aus pos_id und pos machen.

vt1816 19.02.2018 13:54:28

AW: Duplikate löschen
 
Vorschlag: Passe Dein INSERT entsprechend an, dass nur die aktuall geänderten Datrensätze wirklich protokolliert werden (müssen).

Peter69 19.02.2018 17:12:26

AW: Duplikate löschen
 
@vt1816

Das wollte ich auch schon, scheiter hier aber an der Insert Syntax.

Ich brauche ja in etwa:

PHP-Code:

INSERT INTO log (pos_idposedit_byedit_timeVALUES ('" . $recordIDValue . "','" . $counter . "','" . $benutzer . "','" . $timestamp . "'Where pos_id='" . $recordIDValue . "' and 
pos <> " . $counter . " 

Insert und Where ist aber kein Lösung und was anderes habe ich nicht gefunden.
Hast Du hier einen Lösoungsansatz?

vt1816 19.02.2018 17:28:09

AW: Duplikate löschen
 
Wie/wo werden die 250 Datensätze "umsortiert"? Bestimmt mittels Formular?

Peter69 19.02.2018 18:26:39

AW: Duplikate löschen
 
Hallo,
ja ich habe eine Seite mit folgendem Code:

++++++++++++++++++
<script type="text/javascript">
$(document).ready(function()
{
function slideout() {
setTimeout(function() {
$("#debugMess").slideUp("slow", function () {
});
}, 2000);}

$("#debugMess").hide();

$(function() {
$("#customersList").sortable({ placeholder: "customersListHighlight", opacity: 0.5, cursor: 'move', update: function() {
var order = $(this).sortable("serialize") + '&action=updateCustomerPos';
$.post("UpdatePos.php", order, function(theResponse) {
$("#debugMess").html(theResponse);
$("#debugMess").slideDown('slow');
slideout();
});
}
});
$( "#customersList" ).disableSelection();
});
});
</script>
</head>
<body>

<?php
require("inc/db.inc.php");
$showDebugMessage = true;


$q_data = $db->query("SELECT id, CONCAT(tn,' ',title) AS ticket, pos FROM otrsplan ORDER BY pos ASC");
if(mysqli_num_rows($q_data) > 0)
{
echo "<div id=\"wrapper\">\n";
if($showDebugMessage) echo " <div id=\"debugMess\"></div>\n";

echo " <ul id=\"customersList\">\n";
while($r_data = $q_data->fetch_object())
{
echo " <li id=\"recArray_".$r_data->id."\">\n";
echo " <div class=\"customerName\">".$r_data->ticket."</div>\n";
echo " <div class=\"customerName\">".$r_data->pos."</div>\n";
echo " </li>\n";
}
echo " </ul>\n";
echo "</div>";
}
else
{
echo "Es wurde kein Kunde in der Datenbank gefunden";
}
$db->close();
?>
++++++++++++++++++++++++++++++++++++

Diese übergibt die id an das update script
++++++++++++++++++++++++++++++++++++++
<?php
/********************************************************************** ******************
*
Wird aufgerufen wenn die Position eines Eintrages per Drag and Drop veraendert wird. *
*
********************************************************************** ******************/
require("inc/db.inc.php");
require_once("inc/session.php");
$action = $db->real_escape_string($_POST['action']);
$updRecArray = $_POST['recArray'];
$timestamp = time();
$benutzer = $_SESSION['user_id'];

if($action == "updateCustomerPos")
{
$counter = 1;

foreach ($updRecArray as $recordIDValue)

{

$q_update = $db->query("UPDATE otrsplan SET pos = " . $counter . " WHERE id = " . $recordIDValue);
$q_history = $db->query("INSERT INTO otrsplan_history (pos_id, pos, edit_by, edit_time) VALUES ('" . $recordIDValue . "','" . $counter . "','" . $benutzer . "','" . $timestamp . "')");

$counter++;

}

echo $timestamp;
}

$db->Close();
?>
++++++++++++++++++++++++++++++++++++++++++++

Peter69 19.02.2018 18:54:51

AW: Duplikate löschen
 
Ich habe jetzt einen Select gefunden, der fast alles kann was ich brauche..

Select id, pos, pos_id, edit_by, edit_time FROM otrsplan_history Where Exists (SELECT pos_id FROM otrsplan_history DUP WHERE otrsplan_history.pos = dup.pos AND otrsplan_history.pos_id = dup.pos_id AND otrsplan_history.id <> dup.id)
ORDER BY pos;

liefert mir:

id pos pos_id edit_by edit_time
417 7 1 1 1519057747
7 7 1 1 1519047921
212 7 1 1 1519057714

Wenn ich jetzt noch schaffe, nur den letzten und den vorletzten Eintrag zu selektieren, wäre ich glücklich..

Vielen dank für ein Feedback.

LG

Peter

chorn 20.02.2018 08:12:53

AW: Duplikate löschen
 
order by x desc limit 2


Alle Zeitangaben in WEZ +2. Es ist jetzt 03:10:27 Uhr.

Powered by vBulletin® Version 3.8.3 (Deutsch)
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.