MySQL Datensätze in Folge

  • So, vielleicht weiß hier einer eine Möglichkeit, mir fällt nämlich so gar keine ein. Ich habe hier eine Tabelle mit ca. 2 Mio Datensätzen. Darin enthalten ist immer eine Objektnummer und ein Status, z.B. 1 oder 9. Objektnummern und Status sind mehrfach vorhanden (in aller Regel ein Eintrag pro Monat).

    Nun möchte eine Abfrage haben, die mir alle Objektnummern liefert, die den Status 9 mehr als 12mal in Folge haben.

    Nur scheitere ich hier nun komplett, bzw. genauer gesagt am "in Folge". Entweder ich bin auf dem Holzweg, oder mysql kann das nicht.

    Per PHP wäre es möglich, aber da müsste ich dann alles 2 Mio Datensätze einlesen - das wollte ich eigentlich nicht.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • soll das einmalig sein, regelmäßig oder laufend?

    bei einmalig würde ich das vermutlich über einen Export und exel oder access versuchen - allerdings mit 2millionen datensätzen - kA ob das geht und laufend mit einer neuen spalte die hochzählt, würde aber erst funktionieren nach dem eingebaut und das script, dass die Datenbank füllt angepasst wurde. Ist jetzt vermutlich sehr laienhaft, aber könnte funktionieren.

    Frei nach Dieter Nuhr
    Das Internet ist zum Lebensraum der Dauerbeleidigten geworden, die immer einen Grund finden, anderen irgendetwas vorzuwerfen, um sich selbst moralisch zu erhöhen.

  • Hm... "regelmäßig oder laufend"
    eine Mischung davon :) Die Verarbeitung sollte schon öfters sein, aber keine Ahnung wie oft genau. Einmal am Tag? 2 mal pro Stunde? Kommt drauf an.

    Das mit dem Zähler habe ich mir auch schon überlegt. Also immer den Zähler eins erhöhen, bis es einen Statuswechsel gibt und dann wieder bei 1 beginnen. Genau so würde das auch mit PHP gehen. In die Datenbank schreiben wollte ich diesen "statistischen Belast" aber eigentlich nicht. Wobei, wenn es gar nicht anders geht, dann gut, dann halt so.

    Wobei das mit dem Zähler aber auch nicht wirklich besser werden dürfte, denn hochzählen müsste ich den ja auch mit PHP und dazu alle anderen Datensätze davor auslesen, ob die den gleichen Status haben oder nicht. Ich denke mal, dass ich da dann auch gleich alles on-the-fly berechnen kann.

    Wobei, da müsste ich jeweils nur den vorherigen auslesen. Wenn gleicher Status, dann Zähler +1 ansonsten Zähler = 1. Das würde aber bedeuten, dass ich da dann für alle Objekte eine extra Query absetzen müsste, also ca. 4000 auf einmal.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • ohh ja das sollte gehen.

    kannst du mal deine Abfrage hier posten? Ich versuche die mal zu ergänzen. Gehen tut datt auf jeden Fall. Hättest mal vor 9 Jahren gefragt, da wäre das aus der Pistole geschossen gekommen.

    wenn etwas möglich erscheint mach ich das, wenn das nicht klappt gehts ans unmögliche und ansonsten das undenkbare.

    - nun stolz rauchfrei - Ich denke also Bing ich!

    Support 24h Bereitschaft 0173 6107465 - NUR Für Kunden von SEO NW!

  • Alex
    Welche Abfrage? Ich habe keine, Suche ja eine :)

    Also irgendwas in der Art
    SELECT objekt FROM Tabelle WHERE status = 9 HAVING count(id) >= 12 ... aber das nur fortlaufend und kein anderer Status dazwischen.

    In der DB kann es ja auch so aussehen:
    10x Staus 9
    1x Status 1
    10x Status 9

    Diesen Datensatz darf die Abfrage dann nicht liefern. HAVING count(id) würde es aber tun, da count hier 20 ist.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • also zählen kannste mit count. musste aber mit einem where verknüpfen, damit du den operator einfügen kannst.

    WHERE COUNT(*) > 12 ?
    musste nat noch tabelle/spalte auswählen usw.

    wennste da hilfe brauchst mach ich dir das auch noch fertig.

    wenn etwas möglich erscheint mach ich das, wenn das nicht klappt gehts ans unmögliche und ansonsten das undenkbare.

    - nun stolz rauchfrei - Ich denke also Bing ich!

    Support 24h Bereitschaft 0173 6107465 - NUR Für Kunden von SEO NW!

  • "WHERE COUNT(*) > 12 ?"

    Ja nee, so einfach ist das nicht. Daher sagte ich ja "fortlaufend" bzw. in Folge.

    In der DB kann stehen
    [COLOR="#FFA07A"]Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9[/COLOR]
    [COLOR="#AFEEEE"]Status 1[/COLOR]
    [COLOR="#FFA07A"]Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9
    Status 9[/COLOR]

    Bei dem WHERE COUNT(*) > 12 würde es hier zutreffen, denn Status 9 ist 20 mal vorhanden - aber nicht in Folge. In Folge sind es nur 10 mal.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • wird es sicherlich geben. Da bin ich mit meinem MYSQL schon am Limit.
    Ich habe allerdings einiges gefunden über Google. "Mysql count sequence" sollte dich zum Ziel führen.
    bin grade am Kassen Programmieren :)

    wenn etwas möglich erscheint mach ich das, wenn das nicht klappt gehts ans unmögliche und ansonsten das undenkbare.

    - nun stolz rauchfrei - Ich denke also Bing ich!

    Support 24h Bereitschaft 0173 6107465 - NUR Für Kunden von SEO NW!

  • Ich geb da mal ein Danke für... Weiß zwar nicht, ob das das richtige ist, aber "Mysql count sequence" hört sich sehr vielversprechend an.

    "bin grade am Kassen Programmieren"
    Und ich am Nähen ... bin also wieder weg und stech mir in den Finger ;)

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Also, habe mir das mal angesehen. Es hörte sich gut an, aber scheint nicht das zu sein, nach was es klingt. Aber eine andere Idee kam mir dabei... Subselect.

    Das Problem war ja eigentlich das Eingrenzen, denn ein count() über alles geht nicht (können ja andere Status dazwischen sein). Dann ein Versuch mit "in den letzten 12 Monaten". Problem auch hier, dass der Status 9 in aller Regel für einen Monat ist, es aber nicht sein muss. Wäre aber der Startwert bekannt, ab dem gecountet werden darf, dann müsste das gehen...

    So zusammengesponnen ... hab jetzt aber erst mal hungen....

    Eine normale Query mit einem Count() für die Status 9. Als Bedingung aber nicht "letzten 12 Monate", sondern ein Subselect ala "max(id) WHERE status != 9"

    Also was in der Art:
    SELECT count(id) AS anzahl From Tabelle WHERE status = 9 AND id > (SELECT MAX(id) FROM Tabelle WHERE status != 9)

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Ah, das scheint zu gehen... Ob die Daten stimmen, keine Ahnung, aber Ergebnisse kommen schon mal :)

    AUsführungszeit: 0,08 Sekunden

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • ja super :)
    Bin grade am überlegen was du da rausgeabfragt hast.
    HAVING anzahl > 12
    Having hab ich im Nachhinein auch gedacht. Es gab ja verschiedene Codeschnipsel die ich mir angeschaut hatte.

    Ich habe jetzt gemerkt das ich irgendwie! MySQL viel schlechter drauf habe als vor ein paar Jahren. In der Ausbildung war ich wesentlich fitter.

    Bin was aus der Übung, ich habe wirklich das Gefühl als wenn neues "altes" überschreibt im Kopf.
    Aber gut

    Kopf ist schwer, ich konzentriere mich nun auf andere sachen.
    Trotzdem ärgert es mich.

    wenn etwas möglich erscheint mach ich das, wenn das nicht klappt gehts ans unmögliche und ansonsten das undenkbare.

    - nun stolz rauchfrei - Ich denke also Bing ich!

    Support 24h Bereitschaft 0173 6107465 - NUR Für Kunden von SEO NW!

  • Zitat

    ich habe wirklich das Gefühl als wenn neues "altes" überschreibt im Kopf


    Willkommen im Club. Das Gefühl habe ich schon lange. Was ich vor 5-10 Jahren im Schlaf konnte, dann längere Zeit nicht brauchte, habe ich aktuell gänzlich vergessen und muss mich wieder einlesen.

    Zitat

    Bin grade am überlegen was du da rausgeabfragt hast.


    Wie gesagt, das ist eine Datenbank mit 2 Mio Einträgen. Jeden Monat kommen da so 4.000 bis 7.000 hinzu. Im Grund ist es eine Art Logfile, in dem alle Laufzeiten (von bis) der einzelnen Objekte stehen. Laufzeiten können regulär sein (Status 1) oder eben andere Gründe haben. Hier ging es mir nun um Status 9 um darauf reagieren zu können.

    Der Sinn war bzw. ist, die Objekte zu finden, die aktuell einen gewissen Status haben und diesen auch eine gewisse Anzahl in Folge hatten. Also im Beispiel als "12x Status 9 in Folge.". Also, jetzt aktuell Status 9 und die vorherigen 12 auch. Wie gesagt, diese "Logeinträge" erfolgen nicht unbedingt gleich. Die kommen in aller Regel monatlich und haben eine Laufzeit (von bis) von einem Monat, dem muss so aber nicht sein. Zudem kommen auch noch die Status 2-8 hinzu. Eine Abfrage nach count() über alle brachte also nichts, da der count dann ja alles zählt, egal in welcher Reihenfolge die Daten vorliegen. Das ganze auf "die letzten 12 Monate" zu beschränken auch nicht, da der Zeitraum eben nicht 1 Monat sein muss.

    Dann kam ja weiter oben das von Guppy und auch schon das Angedachte von mir. Den Statuswechsel zu erkennen. Hier war ich dann aber auf einem anderen Lösungsweg, an dem ich scheiterte.

    Da ich ja nur die brauche die aktuell Status 9 und eine gewisse Anzahl direkt davor haben, reicht es mir, den letzten Datensatz zu finden, bei dem der Status vom Objekt nicht 9 ist. Wie gesagt, das ist in aller Regel der 12. letzte, kann aber auch der 10. oder der 15. von hinten sein. Also eine Abfrage nach der ID mit dem letzten nicht 9 Status. Das ist dann der letzte Statuswechsel. Anschließend kann alles nach diesem Datensatz mit count() erfasst werden. Das können dann ja nur welche mit Status 9 sein, denn der letzte nicht 9 wurde ja vorher ermittelt.

    So, dann das HAVING mit in die Query, damit der mir auch nur die ausgibt, die nach dem Statuswechsel mehr als 12 haben. Ohne HAVING gibt er alle aus, die aktuell Status 9 haben, egal wie viele bis zum, Statuswechsel vorkommen.

    So, nun habe ich also dann die Objekte, die einen gewissen Status aktuell haben und den selben Status davor schon über eine gewisse Anzahl hinweg hatten. Der Sinn ist nun hier, den Vorgang im Script dann zu unterbrechen. Also wenn einer schon 12x Status 9 in Folge hatte, dann dem keinen Status 9 mehr geben oder zulassen, erst wieder dann, wenn ein anderer vergeben wurde.

    Frei gesagt: Du kannst 12 mal links abbiegen. Danach wird dicht gemacht und du musst rechts abbiegen, stehen bleiben, geradeaus fahren oder sonst was. Hast Du das getan, dann darfst Du wieder links, 12x, dann wird wieder dicht gemacht usw.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(

  • Oh ja, das habe ich nun schon seit Monaten gesucht. Hatte das damals im System laufen und bei den ganzen Serverumzügen irgendwie die Datei verloren. Nicht mehr gefunden. Genau die Query brauche ich :) Muss die nun nur irgendwie umbauen, dann jetzt ist sie zu langsam. Sind nun aber auch an die 30 Mio Datensätze ;)

    Count oder Having > 12 hätte da eben nicht funktioniert, also nicht als einfache Version, denn wie im Bild ersichtlich, gibt es dort 16 mal den Status 9. Ich brauche aber nur die, die am Ende eine Serien von mindestens 12 haben. Die Berechnung von Mysql ist hier nun 14 und das stimmt.

    Wenn ein Mensch nicht um dich kämpft, hat er nur gewartet, dass du gehst. ;(