![]() |
Harte SQL-Nuss - Abfrage formulieren
Moin...
Ich habe da eine knobelaufgabe, die meine Kenntnisse Überfordert... Ich habe einen Haufen Quasi zusammenhangloser Datensätze (Die haben einen Zusammenhang, der hierfür keine Rolle spielt) - eine Art Logfile. Nun markiert ein Datensatzt den Beginn eines Ereignisses (Code = x) und ein Datensatz das Ende eines Ereignisses (Code = y). Haben will ich alle Datensätze, die innerhalb dieses Ereignisses angelegt wurden. jetzt müsste ja eine Abfrage die in etwas so ausschaut das Problem lösen:
Delphi-Quellcode:
Oder so ähnlich...
SELECT * FROM TABELLE WHERE beginnzeit BETWEEN
(SELECT beginnzeit AS Beginn FROM DieSelbeTabelle WHERE code = x) AND (SELECT beginnzeit AS Ende FROM DieSelbeTabelle WHERE code = y); Nun ist es aber ja so, dass BETWEEN zwei Values haben will und nicht zwei tabellen... Ich habe auch schon allerhand mit Inner Join's rumhantiert, aber irgendwie will das nicht :lol: Das Problem ist zusätzlich, dass ich darauf angewiesen bin, dass ich nur eine Anfrage absetze und ebenfalls nur eine Tabell zurückbekomme. Sonst hätt ich Delphi das sortieren lassen nachdem ich alles übertragen hätte... :) Das kann ich zwar immernoch, aber es ist A.) nicht besonders elegant und B.) recht viel Datensalat... Wär echt cool, wenn einer der SQL-Cracks mal einen Tip für mich hätte... Bis denne... |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo,
dein Beispiel sollte eigentlich funktionieren. Welche DB und welche Komponenten verwendest du? |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo Tonic1024,
Dein Select sollte so funktionieren, vorausgesetzt das Ergebnis der beiden SubQueries liefert nur einen Datensatz. |
Re: Harte SQL-Nuss - Abfrage formulieren
Hm, ja. Ihr habt ja Recht.
Und genau da liegt das Problem. Da der Zeitraum vom User festgelegt werden können muss, kann ich mich da ja nicht drauf verlassen... Können auch 2, 4, 100 sein... Im Moment - in der TestPhase - benutze ich nur den Borland Datenbank-Explorer um einen Funktionsfähigen String auszuprobieren. Das DBMS ist IB6 via ODBC. Ob ODBC im Programm so bleibt ist aber noch die Frage... |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo Tonic1024,
das verstehe ich jetzt nicht. Ein Zeitraum wird doch immer nur von zwei Datümern begrenzt. Wie kann das ein User anders festlegen? |
Re: Harte SQL-Nuss - Abfrage formulieren
Äh... die Frage verstehe ich jetzt aber nicht... :-D
Es handelt sich um eine Art Logfile... Das Ereignis kann auch zweimal am Tag auftreten, aber der User kann sich alle ereignisse der ganzen Woche anzeigen lassen... sind also 28 ereignisse. 2 mal start und 2 mal ende pro Tag - rein fiktiv... |
Re: Harte SQL-Nuss - Abfrage formulieren
Das wären dann aber mehrere Zeiträume, also z.B. einma von 07:30 bis 09:15 und dann noch einmal von 10:25 bis 11:00. Verstehe ich das jetzt richtig?
|
Re: Harte SQL-Nuss - Abfrage formulieren
Und genau da liegt der hase im Pfeffer
Ich benötige Alle Zeiträumedie zu dem Ereignis gehören wobei mehrere Ereignis-Zeiträume zu einem vom User ausgewählten Zeitraum gehören. Ich habe also, wie ich in der Frage versucht habe zu formulieren, eine Tabelle mit Start-Ereignissen und eine Tabelle mit Ende-Ereignissen als Resultat der SubQueries. Das geht nicht mit Between. Soweit war ich schon... Ich versuche gerade das mit Joins zu realisieren, damit ich diese "Makro-Tabelle" dann mit WHERE, AND, OR etc selectieren kann... Oder geht das etwa garnicht?!?! [zitter] |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo Tonic,
falls du mehrere Datensätze bekommst, solltest du das Ergebnis der Unterselect - Statement mit z.B. MAX auf einen Wert beschränken:
SQL-Code:
SELECT * FROM TABELLE WHERE beginnzeit BETWEEN
(SELECT MAX(beginnzeit) AS Beginn FROM DieSelbeTabelle WHERE code = x) AND (SELECT MAX(beginnzeit) AS Ende FROM DieSelbeTabelle WHERE code = y); |
Re: Harte SQL-Nuss - Abfrage formulieren
Das Problem ist Umfangreich, ich weiss... hab selbst ne Weile gebraucht bis ich es begriffen hab...
Also, nehmen wir der Einfachheit an es handelt sich um ein Server Log-file mit Ausfall-Meldugen und Störung-behoben-Meldungen (etwas an den Haaren herbeigezogen - ich weiss). Ich müsste dann schon alle Ausfälle sehen inklusive der Datensätze die dazwischen liegen z.B. Aktionen die wegen der Störung nich ausgeführt wurden oder fehlgeschlagene Versuche den Fehler zu beheben. Ich möchte aus Performance-Gründen nur ungern ALLE angefallenen Datensätze des Ausgewählen Zeitraums übertragen und Delphi schauen lassen ob ein Ausfall drin ist, obwohl das wohl einfacher wäre. |
Re: Harte SQL-Nuss - Abfrage formulieren
Hi Tonic
Ich denke, dass mit Datumseingrenzungen nicht der gewünschte Effekt erzielt werden kann - damit wird man nicht die Einträge zu einem Event bekommen. Hast du die Möglichkeit in die Table eine zusätzliche Spalte einzufügen ? - wenn ja, dann vergib doch bei jedem Start eine "Eventnummer" - jeder Eintrag, der zu dem Event gehört, bekommt diese Nummer - Danach kann man dann einfach selektieren... |
Re: Harte SQL-Nuss - Abfrage formulieren
Moin darkstone...
Die Idee ist gut, leider passt sie nicht auf mein Problem... :lol: Nee, im Ernst, würde ich gerne machen... Aber die Datenzätze werden von 'zig einzelnen kleinen Bordcomputern (Außendienst) erzeugt. Damit das nicht alles durcheinander läuft sorgt ein Einlese-Server für Ordnung. Diese ollen BC's sind aber strunzen dämlich. Die legen für dieses Event zwischen 2 und x Datensäte an. zu erkennen an einem Start-Datensatz und einem Ende-Datensatz. Wer dich das ausgedacht hat... Jeder einzelne Datensatz hat aber mit dem Event selbst nichts zu tun, außer dass er innerhalb des selben zeitraums wie der Event gewesen ist. Pseudo-Primärschlüssel ist somit Datum/Uhrzeit kombiniert. Ich stehe vor einem ausgewachsenen problem... :( |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo,
versuche doch mal
SQL-Code:
SELECT * FROM TABELLE WHERE beginnzeit BETWEEN
(SELECT DISTINCT beginnzeit AS Beginn FROM DieSelbeTabelle WHERE code = x) AND (SELECT DISTINCT beginnzeit AS Ende FROM DieSelbeTabelle WHERE code = y); Gruss Christof |
Re: Harte SQL-Nuss - Abfrage formulieren
Da wirst du mit Ansi-SQL nicht weiter kommen.
Das Problem ist, das Du in der Abfrage selber eine gewisse Logik benötigst, die sich durch reines SQL nicht abbilden lässt. Prinzipiell sieht Deine Abfrage so aus: Hole alle Anfangszeiten für jeden Datensatz in dieser Abfrage: - hole zugehörigen Endzeitpunkt - hole dazwischen liegende daten und an der zweiten Zeile scheiterst Du. (Das mit dem zugehörigen Endzeitpunkt deswegen weil es theoretisch sein kann, daß sich Zeitbereiche überschneiden. Beispiel: 1. 09:00 Uhr - 12:00 Uhr, 2. 11:45 Uhr bis 13:00 Uhr. Auch wenn das vielleicht praktisch nicht so vorkommen kann, so wie Du das Datenmodell beschrieben hast ist es möglich und sollte entsprechend auch behandelt werden können.) Das ganze lässt sich über Transact-SQL z.b. beim MS SQL - Server abbilden, bei Oracle geht das auch mit servergespeicherten Prozeduren. Ob das mit Interbase abbildbar ist weiss ich leider nicht. Ansonsten müsstest Du diese Schleife tatsächlich programmatisch abbilden, also erstmal alle End- und Startzeitpunkte selektieren, die jeweils zusammengehörigen raussortieren und dann pro Bereich eine einzelne between-Abfrage loslassen. |
Re: Harte SQL-Nuss - Abfrage formulieren
Ist anhand von "Code" zu erkennen welchem ereignis es gehört.
Oder ist es nur eine sequence-generierte Zahl. Welche Spalten hat deine Tabelle? |
Re: Harte SQL-Nuss - Abfrage formulieren
Moin...
@Christof Damit würde zwar die Abfrage funktionieren, aber mein Problem nicht gelöst... :roll: @phoenix Genau das ist es... Soweit war ich mittlerweile auch gekommen. Das mit dem Endzeitpunkt ist zwar richtig, aber zu vernachlässigen. Das mit dem Server war nur als vergleich gedacht. Und analog zu diesem Beispiel müsste er erst wieder repariert werden, bevoer er erneut ausfallen könnte. Gottseidank hat die Informatik keine Gewalt über die Physik :-D eine Zweite Abfrage kann ich aus Programm-technischen Gründen nicht starten. Es wird ein Modul für eine Software die diesen Fall nicht vorsieht. Meine Überlegung ging dahin, dass ich mit den Sub-Querys ja je eine Tabelle erzeuge. Die wollte ich joinen lassen und dann selektieren. Bin aber auch da gescheitert...(werd aber weiter versuchen) Könnte sein, dass die SQL damit wirklich überfordert ist... @GeorgeW ich habe ServerID, Datum, Uhrzeit von, Uhrzeit bis, EreignisID, EreignisBeschreibungID, EreignisInfoID Ein bestimmtes Ereignis begrenzt viele andere Ereignisse. Quasi so: (wieder das Server-Beispiel - Multitasking beherrscht dieser Server nicht!)
Code:
gibt noch mehr Felder, die damit in keinem Zusammenhang stehen. Key ist eine autoincrement ID.
Gerät4, 22.2.2002, 22:22, 22:23, Mail Ereigniss, Mailbewegung, Mail eingegangen
Gerät4, 22.2.2002, 22:23, 22:26, Mail Ereigniss, Neue Mail erstellt, NULL Gerät4, 22.2.2002, 22:26, 22:26, System Ereignis, Ausfall, Fehler aufgetreten Gerät4, 22.2.2002, 22:26, 22:28, Virus Ereignis, AV-Update durchgeführt, NULL Gerät4, 22.2.2002, 22:28, 22:32, Mail Ereigniss, Mailbewegung, Mail ausgegangen Gerät4, 22.2.2002, 22:32, 22:32, System Ereignis, Ausfall, Fehler behoben Interessant ist für mich der Ausfall und alles was zwischen Beginn und Ende passiert ist. BTW: es gibt auch mehr als nur ein Gerät, aber soll nicht das Problem sein... bis denne... |
Re: Harte SQL-Nuss - Abfrage formulieren
Hallo,
also ich glaube nicht das das mit einem SQL Kommando realisierbar ist. Eine Möglichkeit sind StoredProcedure auf dem SQL Server. Damit geht so etwas, oder mit einem View damit geht auch so etwas. Ich kenne die Systemumgebung nicht ob so etwas bei dir möglich ist. Gruss Christof |
Re: Harte SQL-Nuss - Abfrage formulieren
Falls du für den Zeitraum jedes Ereignisses alle anderen zum gleichem Zeitraum haben willst.
Kannst du das hier versuchen. Ich verwende eine Oracle DB - es kann deshalb sein, dass einige Sachen bei dir nicht funktionieren.
SQL-Code:
SELECT ev_a.device,
ev_a.ev_descr Description, ev_a.ev_info info, decode(ev_a.ev_action, 'NULL', 'keine Aktion', ev_a.ev_action) action, ev_a.ev_date event_date, ev_a.ev_st_tm start_time, ev_a.ev_en_tm end_time, ev_b.device "conc. Device", rpad(ev_b.ev_descr, 20, ' ') || ': ' || rpad(ev_b.ev_info, 25, ' ') || ' - ' || decode(ev_b.ev_action, 'NULL', 'keine Aktion', ev_b.ev_action) "conc. Event", ev_b.ev_st_tm || ' - ' || ev_b.ev_en_tm "Time" FROM (SELECT t.device, t.ev_descr, t.ev_info, t.ev_action, t.ev_date, t.ev_st_tm, t.ev_en_tm, to_date(to_char(t.ev_date, 'dd.mm.yyy') || ' ' || t.ev_st_tm, 'dd.mm.yyyy hh24:mi') st_dttm, to_date(to_char(t.ev_date, 'dd.mm.yyy') || ' ' || t.ev_en_tm, 'dd.mm.yyyy hh24:mi') en_dttm, ROWID FROM [TABELLE] t) ev_a, (SELECT t.device, t.ev_descr, t.ev_info, t.ev_action, t.ev_date, t.ev_st_tm, t.ev_en_tm, to_date(to_char(t.ev_date, 'dd.mm.yyy') || ' ' || t.ev_st_tm, 'dd.mm.yyyy hh24:mi') st_dttm, to_date(to_char(t.ev_date, 'dd.mm.yyy') || ' ' || t.ev_en_tm, 'dd.mm.yyyy hh24:mi') en_dttm, ROWID FROM [TABELLE] t) ev_b WHERE (EV_B.st_dttm BETWEEN ev_a.st_dttm AND ev_a.en_dttm OR EV_B.en_dttm BETWEEN ev_a.st_dttm AND ev_a.en_dttm) AND ev_a.ROWID != ev_b.ROWID ORDER BY ev_a.device, ev_a.st_dttm, ev_a.ev_action, ev_b.st_dttm Ich nahm die Werte die du gepostet hast und habe diese Spalten erstellt: device varchar2(20) ev_date date ev_st_tm varchar2(5) ev_en_tm varchar2(5) ev_descr varchar2(100) ev_info varchar2(100) ev_action varchar2(100) Damit erhältst du halt eine Übersicht. Aber ich glaube ich habe dein Problem nicht ganz verstanden. Außer es geht um debugging der DB (du schriebst Systemausfall, Virusbefall) Robert |
Re: Harte SQL-Nuss - Abfrage formulieren
Moin...
Danke, ich werds probieren. Aber ich komme dies Wochenende nich mehr dazu... vorübergehende Umorientierung des Projektziels... Es gibt immer Leute die wichtiger sind als Andere :) Das Problem liegt mir aber immer noch am Herzen... nächste Woche werd ich mal wieder ein paar Stündchen abzwacken... Es geht eigentlich nur darum aus einer langen Tabelle einen Block von einem Start-Datensatzt bis zu einem Ende-Datensatz auszulesen - egal was drin steht. Dann weiter unten in der Tabelle, wenn wieder ein Start-Datensatzt kommt weiterlesen und beim Ende-Datensatz aufhören. Das Problem ist ja, dass das DBMS für jeden Datensatz schaut ob die Bedingung zutrifft oder nicht. Ich will aber ja alle Datensätze (als Block) haben die Zwischen zwei Datensätzen stehen. Und das nicht nur einmal sondern sooft wie eine Start-Daten-Ende Kombinationen vorkommen. Das Beispiel mit dem Server habe ich nur gebracht, weil das reale Thema viel zu umfangreich und abstrakt ist - selbst für mich :lol:. In der Tat ist es aber eine Art Logfile, dass wie oben geschildert ist aufgebaut ist. Danke erstmal... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:34 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz