PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : MySQL Frage



DonnerGott
12.07.2009, 02:16
Hallo Leute,

hat von Euch jemand eine Ahnung wie ich doppelte Einträge in der MySQL Datenbank filtern kann?

Ich arbeite mit BOS2Web und mehreren Funkservern die mir manchmal die Einträge doppelt bzw. dreifach in die Datenbank schreiben, deshalb sollen die direkt in der DB gefiltert, um nicht mehrfach auf der BOS2Web Seite angezeigt werden.

Meine Vorstellung ist, wenn ein Datensatz neu übertragen wird, soll die MySQL DB überprüfen , ob dieser Datensatz innerhalb der letzten 15 sek. schon mal gesendet wurde, also im Prinzip sind die Datensätze dann bis auf den TimeStamp gleich.

mfg

Shinzon
12.07.2009, 04:46
Moin..

Spricht prinzipiell nichts dagegen, dafür müsste man nur den "eintragenden"
Query ein wenig anpassen .. hast du darauf Zugriff ?

Gruss,
Tim

DonnerGott
12.07.2009, 10:24
Hallo,

Zugriff ja, aber leider so gut wie keine Ahnung von SQL.

Sag mir bitte was ich machen soll.

mfg

Shinzon
12.07.2009, 11:55
Am logischsten wäre wohl:

Nenne die aktuelle Abfrage. Denn woher soll ich die kennen ? ;)

Gruss,
Tim

DonnerGott
12.07.2009, 12:00
reicht dir auch ein screenshot?

Shinzon
12.07.2009, 12:03
Nein. Ich brauche Text ..

Na sicher reicht nen Screenshot, hauptsache man kann was lesen ..

DonnerGott
12.07.2009, 12:05
bitte schön

Shinzon
12.07.2009, 12:25
Und wo steht da das von dem "Datenbefüller" ausgeführte Query ?

phpMyAdmin ist zwar schön zum Angucken, aber verändern muss man das Query,
das dein Programm zum Datenbefüllen ausführt.

DonnerGott
12.07.2009, 12:33
aso,

vb code

strSQL = "UPDATE fms_fz SET status_fz='" & strSimple(6) & "', tki='" & strSimple(9) & "', user='" & user & "' WHERE kennung='" & strSimple(1) & "'"

ich hoffe, das du hier mit was anfangen kannst.

Shinzon
12.07.2009, 12:45
Dieses Statement bearbeitet eine schon vorhandene Zeile, es fügt keine neue ein..

Hast du die falsche Stelle erwischt? ;)

Ich schau trotzdem mal mit dem Screenshot, ob ich nen "Einzeiler" gezaubert kriege..
Der müsste übrigens in jeder Datenquelle laufen, sonst bringt es nichts..

Gruss,
Tim


*EDIT* Bitte finde doch mal eine Zeile, in der "INSERT INTO" am Anfang steht ;)

Sollte es (nicht unbedingt SQL-Standard) nur die UPDATE-Zeile geben, könntest
du (in allen Datensendern) folgendes versuchen:



strSQL = "UPDATE `fms_fz` SET `status_fz`='" & strSimple(6) & "', `tki`='" & strSimple(9) & "', `user`='" & user & "' WHERE `kennung`='" & strSimple(1) & "' AND DATE_SUB( NOW( ), INTERVAL 15 SECOND) <= `timestamp`;"


Zur Erklärung: Das Original-Statement hat einen "WHERE" Abschnitt, je nach Ergebnis
dieses Abschnitts wird das UPDATE durchgeführt. Neben den fehlenden " ` " für Feld-
Bezeichner habe ich am Ende des Originals den Zusatz "AND ..." angefügt. Im
Zusatz wird die aktuelle Uhrzeit zum Zeitpunkt der Abfrage und "15 Sekunden" subtrahiert,
also ein Zeitstempel "erzeugt", der 15 Sekunden vor der Abfrage lag. Diese Zeit wird
mit dem Zeitstempel der aktuellen UPDATE-Reihe verglichen. Ist die Aussage (<=)
wahr (und alle anderen WHERE-Expressions auch), wird das Update ausgeführt, ansonsten
nicht. Da ich nur diese Zeitstempel-Abfrage angefügt habe, ist also das Ziel erreicht,
einen Datenbankeintrag nur dann zu aktualsieren, wenn innerhalb der letzten 15 Sekunden
keine andere Änderung derselben Kennung vorgenommen wurde.
An sich passt das aber nicht, da ein "UPDATE"-Befehl einfach nicht passt für die Aufgabe,
die hier geleistet werden soll (INSERT INTO) ..

Naja, zumindest weisst du also jetzt, wie du "die letzten 15 Sekunden" abfragst ^^

Firefighter Heiti
12.07.2009, 14:43
du könntest das ganze auch mit dem MySQL Statement GROUP BY machen

so habe ich das gelöst bei der Digitalalarmierung:


"SELECT * FROM pocsag GROUP by ric,funktion,meldung,datum,uhrzeit ORDER BY id DESC"

DonnerGott
12.07.2009, 14:57
danke schön,

gibt es keine möglichkeit wo ich einen befehl in der db eintragen kann der bei jeder aktualisierung die einträge überprüft?
ich finde dass das einfacher wäre als die upload softwae anzugleichen.

mfg

Firefighter Heiti
12.07.2009, 15:32
die zeile die ich gepostet habe ist, wird beim abruf eingefügt, sprich in das Skript, über das du die datenbank abfragst

DonnerGott
12.07.2009, 16:18
aah, ok, danke

DonnerGott
12.07.2009, 16:24
uiuiui,

kannst du mir helfen die zeile einzubinden?

das ist mein code

$sql = 'SELECT date_format(h.timestamp, "%H:%i:%s") as timestamp, date_format(h.timestamp, "%d.%m.%Y") as datum, h.kennung, h.ID, h.tki, h.status, h.richtung, f.fahrzeug, f.rufname '
.'FROM '.$tbl_fms_hist.' h LEFT JOIN '.$tbl_fms_fz.' f ON(h.kennung=f.kennung) '
.'ORDER BY h.timestamp DESC '
.'LIMIT '.(isset($limitfms) ? $limitfms : 100);

mfg

DaRake
12.07.2009, 16:47
Hallo,


du könntest das ganze auch mit dem MySQL Statement GROUP BY machen

so habe ich das gelöst bei der Digitalalarmierung:

hmm, das filtert bei mir leider keine doppelten Meldungen heraus.

Kannst du mir mal deinen kompletten Quelltext zur Verfügung stellen?

Gruß,
Sebastian

Firefighter Heiti
12.07.2009, 22:21
Hoffe ich kann mit dem Code ein bisschen verwirrung <strike>stiften</strike> rausnehmen

<?php header('Content-Type: text/html; charset=iso-8859-1'); ?>
<?php include("aufschluesselung.php");
$timestamp = time();
$Verzögerung = $timestamp - 60*2;
$Verzögerung = date("H:i:s",$Verzögerung);
?>
<div id="content">
<div class="feature">
<h3 align="center">Die letzten 10 Alarmierungen</h3>
<table width="100%" align="center" border="0" cellpadding="7" cellspacing="5">
<tr bgcolor="#cc0000">
<td width="70"><b><font color="#FFFFFF">Datum:</font></b></td>
<td width="70"><b><font color="#FFFFFF">Uhrzeit:</font></b></td>
<td width="155"><b><font color="#FFFFFF">Alarmiert:</font></b></td>
<td width="100"><b><font color="#FFFFFF">Ort:</font></b></td>
<td width="150"><b><font color="#FFFFFF">Straße:</font></b></td>
<td width="181"><b><font color="#FFFFFF">Stichwort:</font></b></td>
<td width="60"><b><font color="#FFFFFF">Karte:</font></b></td>
</tr>

<?php
include("config.php");
$abfrage = "SELECT * FROM pocsag GROUP by ric,meldung,funktion,datum,uhrzeit ORDER BY id DESC LIMIT 10";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
// Initialisieren eines Strings, welches als Quellstring genutzt werden soll
$quellstring = "$row->meldung";
// String mit einem Leerzeichen als Trennerzeichen aufteilen
$woerter = explode (',', $quellstring);
// Anzahl der Worte im Beispielsatz
// echo 'Anzahl der Worte im String: ' . sizeof ($woerter) . '<br>';
// Inhalt des Arrays ausgeben
//print_r ($woerter);
// Über den Trenner maximal drei Elemente extrahieren
// $ersten_drei = explode (' ', $quellstring, 5);
// Und wieder das Ergebnis anzeigen
// print_r ($ersten_drei);
{
if($row->ric == 1234567 and $row->funktion == 1)
{
$return ='RIC FUNKTION A';
}
elseif($row->ric == 1234567 and $row->funktion == 2)
{
$return ='RIC FUNKTION B';
}
else
{
$return ="$row->ric";
}
echo "
<tr>
<td align=\"left\">".$row->datum."</td>
<td align=\"left\">".$row->uhrzeit."</td>
<td align=\"left\">".$return."</td>
<td align=\"left\">".strtr("$woerter[1]", $trans)."</td>
<td align=\"left\">".strtr("$woerter[2]", $trans)."</td>
<td align=\"left\">".strtr("$woerter[0]", $trans)."</td>
<td align=\"center\"><a target=\"_blank\" href=\"http://maps.google.de/maps?f=q&source=s_q&hl=de&geocode=&q=".strtr("$woerter[2]", $trans)."+".strtr("$woerter[1]", $trans)."\">Zeige Ort</a></td>
</tr>";
}
}
?>
</table>
</div>
</div>

Shinzon
13.07.2009, 00:33
Moin..

Naja, du gehst aber in deinem Code nicht von der Grundannahme aus, das mehrere
Datenquellen evtl. Telegramme doppelt oder dreifach einfügen.

Denn dazu wollte er eine Möglichkeit, die Einträge aus der Datenbank zu löschen.

Die erste Variante, das er beim Einfügen der Daten aus den Datenquellen eingreift,
wenn schon die gleichen Daten vorhanden sind, haben ihm nicht gefallen, eine andere
Darstellung wird es vmtl. auch nicht.

Jetzt aber mit nem Crontab-Skript anzukommen, wird ihm auch wieder nicht gefallen,
aber was er will, das nach jedem Datenbank-Commit ein kleines Reinigungsskript aus-
geführt wird.. na DAS will ich ihm nicht antun, dafür müsste er im besten Falle die
Datenbank neu compilieren..

Gruss,
Tim