Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Optimierungs-Aufgabe

6 views
Skip to first unread message

Lothar Geyer

unread,
Apr 18, 2012, 9:32:45 AM4/18/12
to
Ich habe (vereinfacht) eine Tabelle mit zwei Feldern, eine Zeitangabe TT
und einen Integer-Wert WW. Ich brauche nun eine Abfrage, die mir
folgendes liefert:

- die Anzahl Sätze mit negativen WW-Werten
- die Anzahl Sätze mit WW=0
- die Anzahl Sätze mit positiven WW-Werten

Das alles getrennt für jede Stunden (also von 00:00-01:00, 01:00-02:00
usw. bis 23:00-24:00) und für jeden Wochentag. Insgesamt also 7*24=168
Ergebnisse mit jeweils den drei oben genannten Zählern.

Ich habe natürlich eine Lösung (168 Abfragen), aber die ist mir zu
langsam. Ich suche also die "performanteste" Lösung. Sollte unter Access
und unter SQLserver laufen.

Lothar Geyer

Peter Schneider

unread,
Apr 18, 2012, 3:33:13 PM4/18/12
to
Am 18.04.2012 15:32, schrieb Lothar Geyer:
> Ich habe (vereinfacht) eine Tabelle mit zwei Feldern, eine Zeitangabe TT und
> einen Integer-Wert WW. Ich brauche nun eine Abfrage, die mir folgendes liefert:
>
> - die Anzahl Sätze mit negativen WW-Werten
> - die Anzahl Sätze mit WW=0
> - die Anzahl Sätze mit positiven WW-Werten
>
> Das alles getrennt für jede Stunden (also von 00:00-01:00, 01:00-02:00 usw.
> bis 23:00-24:00) und für jeden Wochentag. Insgesamt also 7*24=168 Ergebnisse
> mit jeweils den drei oben genannten Zählern.

Deine Intervalle sind nicht überlappungsfrei. Du meinst sicherlich (mit
Auflösung Sekunde) von 00:00:00 bis 00:59:59, von 01:00:00 bis 01:59:59 usw, oder?

> Ich habe natürlich eine Lösung (168 Abfragen), aber die ist mir zu langsam.
> Ich suche also die "performanteste" Lösung. Sollte unter Access und unter
> SQLserver laufen.

Schade. Für Oracle hätte ich's parat...

Gruß
Peter

--
The only way to keep your health is to eat what you don't want, drink what
you don't like, and do what you'd rather not. -- Mark Twain

Lothar Geyer

unread,
Apr 18, 2012, 5:39:03 PM4/18/12
to
Hallo Peter,

Am 18.04.2012 21:33, schrieb Peter Schneider:
> ...
> Deine Intervalle sind nicht überlappungsfrei. Du meinst sicherlich (mit
> Auflösung Sekunde) von 00:00:00 bis 00:59:59, von 01:00:00 bis 01:59:59
> usw, oder?

Ja, natürlich. Genau genommen auch nicht 01:00:00 bis 01:59:59, weil
dann die Zeit zwischen 01:59:59 und 02:00:00 verloren ginge. Also
Abfrage in der Form "myDate>=01:00:00 And myDate<02:00:00".

> Schade. Für Oracle hätte ich's parat...

Deine Lösung würde mich trotzdem interessieren. Vielleicht kann ich ja
zumindest eine Idee klauen... ;-)

Lothar Geyer

Siegfried Schmidt

unread,
Apr 18, 2012, 5:46:44 PM4/18/12
to
Lothar Geyer schrieb:

> Ich habe natürlich eine Lösung (168 Abfragen), aber die ist mir zu
> langsam. Ich suche also die "performanteste" Lösung. Sollte unter Access
> und unter SQLserver laufen.

Leg einmalig je eine Tabelle mit den 7 Wochentagen und den 24
Intervalgrenzen an und verwende im Kreuzprodukt beider Tabellen deine
bisherige Abfrage als Unterabfrage.


Siegfried

Lothar Geyer

unread,
Apr 18, 2012, 6:42:13 PM4/18/12
to
Hallo Siegfried,

Am 18.04.2012 23:46, schrieb Siegfried Schmidt:
> ...
> Leg einmalig je eine Tabelle mit den 7 Wochentagen und den 24
> Intervalgrenzen an und verwende im Kreuzprodukt beider Tabellen deine
> bisherige Abfrage als Unterabfrage.

und Du bist sicher, dass das performanter ist? Das Erstellen und
Befüllen der Tabelle ist ja doch relativ aufwändig. Bei einem View würde
wahrscheinlich das interne Kopieren wegfallen - aber dazu kenne ich die
Internas der beiden Datenbanken zu wenig.

Lothar Geyer

Siegfried Schmidt

unread,
Apr 18, 2012, 7:04:20 PM4/18/12
to
Lothar Geyer schrieb:

> und Du bist sicher, dass das performanter ist?

Perfomanter als was? Gegenüber 168 einzelnen Abfragen? Aber sicher.

> Das Erstellen und
> Befüllen der Tabelle ist ja doch relativ aufwändig.

Das einmalig Tippen von 7+24=31 Datensätze kann natürlich dauern,
möglicherweise mehr als 2 Minuten.

> Bei einem View würde
> wahrscheinlich das interne Kopieren wegfallen - aber dazu kenne ich die
> Internas der beiden Datenbanken zu wenig.

Ich weis nicht, was du dabei kopieren willst. Nötig ist es jedenfalls
nicht.

Siegfried

Dieter Nöth

unread,
Apr 19, 2012, 2:00:25 AM4/19/12
to
Lothar Geyer wrote:

> Ich habe (vereinfacht) eine Tabelle mit zwei Feldern, eine Zeitangabe TT
> und einen Integer-Wert WW. Ich brauche nun eine Abfrage, die mir
> folgendes liefert:
>
> - die Anzahl Sätze mit negativen WW-Werten
> - die Anzahl Sätze mit WW=0
> - die Anzahl Sätze mit positiven WW-Werten
>
> Das alles getrennt für jede Stunden (also von 00:00-01:00, 01:00-02:00
> usw. bis 23:00-24:00) und für jeden Wochentag. Insgesamt also 7*24=168
> Ergebnisse mit jeweils den drei oben genannten Zählern.

Für SQL Server:
select
datepart(weekday, TT),
datepart(hour, TT),
sum(case when WW < 0 then 1 else 0 end),
sum(case when WW = 0 then 1 else 0 WW end),
sum(case when WW > 0 then 1 else 0 WW end)
from tab
group by
datepart(weekday, TT),
datepart(hour, TT)

Ob Access inzwischen CASE kennt, wiess ich nicht, ansonsten müsste es
IIF(WW<0,1,0) sein.

Dieter

Lothar Geyer

unread,
Apr 19, 2012, 3:38:46 AM4/19/12
to
Hallo Siegfried,

Am 19.04.2012 01:04, schrieb Siegfried Schmidt:
> ...
>> Das Erstellen und
>> Befüllen der Tabelle ist ja doch relativ aufwändig.
>
> Das einmalig Tippen von 7+24=31 Datensätze kann natürlich dauern,
> möglicherweise mehr als 2 Minuten.

anscheinend habe ich Dich falsch verstanden. Zunächst mal: Ich will drei
Werte für jeweils 24 Stunden pro Wochentag. Das sind 168 Datensätze mit
je drei Werten. Oder sehe ich das falsch?
Du meintest, dass ich einmalig eine Tabelle anlegen und diese mit den
Zählern (Anzahl Sätze mit negativem Wert, Anzahl mit positivem Wert und
Anzahl mit Null) füllen soll. Das ist ja auch Zeit, die die Datenbank
braucht.

Lothar Geyer

Siegfried Schmidt

unread,
Apr 19, 2012, 6:21:31 AM4/19/12
to
Lothar Geyer schrieb:

> anscheinend habe ich Dich falsch verstanden. Zunächst mal: Ich will
> drei Werte für jeweils 24 Stunden pro Wochentag. Das sind 168
> Datensätze mit je drei Werten. Oder sehe ich das falsch?

Wenn du eine komplette Auflistung aller Stunden einer Woche haben
willst, dann brauchst du eine Konstruktion, die den Rahmen dieser
Auflistung mit 168 Zeilen erzeugt. Durch stundenweise Gruppierung der
Daten bekämest du ja nur eine Auflistung jener Stunden, die tatsächlich
mit Nutzdaten belegt sind.

Diese Konstruktion kann auf verschiedene Weise realisiert werden, die
portabelste ist die Verwendung von Hilfstabellen.

> Du meintest, dass ich einmalig eine Tabelle anlegen und diese mit den
> Zählern (Anzahl Sätze mit negativem Wert, Anzahl mit positivem Wert
> und Anzahl mit Null) füllen soll. Das ist ja auch Zeit, die die
> Datenbank braucht.

Es werden keine Zählergebnisse abgelegt, sondern nur die Bedingungen für
die Zählung erzeugt. Wenn in der Tabelle wochentag die 7 Tage und in der
Tabelle stunde die 24 Stunden eingetragen sind, ergibt sich folgende
Abfrage (case-Ausdrücke geklaut von Lothar):

select wochentag.tag, stunde.stunde,
(select count(case when WW < 0 then 1 else 0 end)
from nutzdaten
where datepart(weekday, TT)=wochentag.tag and
datepart(hour, TT)=stunde.stunde) erg1,
(select count(case when WW = 0 then 1 else 0 WW end)
from nutzdaten
where datepart(weekday, TT)=wochentag.tag and
datepart(hour, TT)=stunde.stunde) erg2,
(select count(case when WW > 0 then 1 else 0 WW end)
from nutzdaten
where datepart(weekday, TT)=wochentag.tag and
datepart(hour, TT)=stunde.stunde) erg3
from wochentag, stunde
order by wochentag.tag, stunde.stunde;

Für Access muss datepart() und case angepasst werden.

Siegfried


Siegfried Schmidt

unread,
Apr 19, 2012, 6:23:01 AM4/19/12
to
Korrektur:

case-Ausdrücke geklaut von Dieter, sorry


Siegfried

Lothar Geyer

unread,
Apr 19, 2012, 8:34:38 AM4/19/12
to
Hallo Dieter,

Am 19.04.2012 08:00, schrieb Dieter Nöth:
> ...
> Für SQL Server:
> select
> datepart(weekday, TT),
> datepart(hour, TT),
> sum(case when WW < 0 then 1 else 0 end),
> sum(case when WW = 0 then 1 else 0 WW end),
> sum(case when WW > 0 then 1 else 0 WW end)
> from tab
> group by
> datepart(weekday, TT),
> datepart(hour, TT)
>
> Ob Access inzwischen CASE kennt, wiess ich nicht, ansonsten müsste es
> IIF(WW<0,1,0) sein.

Wow, vielen Dank. Ich habe das inzwischen getestet - und es ist
(gefühlt) 100 Mal schneller als die Schleife die ich bisher hatte. Für
Access habe ich es auch am Laufen, mit einem IIF. Zumindest in Acc2000
gibt es noch kein CASE.

Lothar Geyer

Lothar Geyer

unread,
Apr 19, 2012, 8:37:08 AM4/19/12
to
Hallo Siegfried,
No problem. Ich habe inzwischen die Lösung von Dieter an die
tatsächliche Umgebung angepasst. Es gibt also nur noch eine Abfrage -
und die ist wirklich sauschnell.

Danke für Deine Mühe.

Lothar Geyer

Peter Schneider

unread,
Apr 19, 2012, 3:51:52 PM4/19/12
to
Am 18.04.2012 23:39, schrieb Lothar Geyer:
> Hallo Peter,
>
> Am 18.04.2012 21:33, schrieb Peter Schneider:
>> ...
>> Deine Intervalle sind nicht überlappungsfrei. Du meinst sicherlich (mit
>> Auflösung Sekunde) von 00:00:00 bis 00:59:59, von 01:00:00 bis 01:59:59
>> usw, oder?
>
> Ja, natürlich. Genau genommen auch nicht 01:00:00 bis 01:59:59, weil dann die
> Zeit zwischen 01:59:59 und 02:00:00 verloren ginge. Also Abfrage in der Form
> "myDate>=01:00:00 And myDate<02:00:00".

Deswegen schrieb ich oben in Klammern "Auflösung Sekunde". Wenn die kleinste
Granularität eine Sekunde ist, dann gibt es keine Ereignisse zwischen 01:59:59
und 02:00:00. Das ist z.B. bei Oracle DATE Columns so.

>> Schade. Für Oracle hätte ich's parat...
>
> Deine Lösung würde mich trotzdem interessieren. Vielleicht kann ich ja
> zumindest eine Idee klauen... ;-)

Naja, da Du ja inzwischen von Dieter eine Lösung bekommen hast, spare ich mir
jetzt, das gleich nochmal in Grün (d.h. Oracle SQL) zu schreiben. Außerdem
habe ich gerade Urlaub und versuche, mich von Datenbanken fern zu halten.
Gelingt aber meist nicht ganz ;-)

Lothar Geyer

unread,
Apr 19, 2012, 7:24:30 PM4/19/12
to
Hallo Peter,

Am 19.04.2012 21:51, schrieb Peter Schneider:
> ...
> Außerdem habe ich gerade Urlaub und versuche, mich von
> Datenbanken fern zu halten. Gelingt aber meist nicht ganz ;-)

das Argument wird akzeptiert ;-))

Lothar Geyer

Tim Landscheidt

unread,
Apr 20, 2012, 12:19:56 PM4/20/12
to
Peter Schneider <pschnei...@googlemail.com> wrote:

>>> ...
>>> Deine Intervalle sind nicht überlappungsfrei. Du meinst sicherlich (mit
>>> Auflösung Sekunde) von 00:00:00 bis 00:59:59, von 01:00:00 bis 01:59:59
>>> usw, oder?

>> Ja, natürlich. Genau genommen auch nicht 01:00:00 bis 01:59:59, weil dann die
>> Zeit zwischen 01:59:59 und 02:00:00 verloren ginge. Also Abfrage in der Form
>> "myDate>=01:00:00 And myDate<02:00:00".

> Deswegen schrieb ich oben in Klammern "Auflösung
> Sekunde". Wenn die kleinste Granularität eine Sekunde ist,
> dann gibt es keine Ereignisse zwischen 01:59:59 und
> 02:00:00. Das ist z.B. bei Oracle DATE Columns so.
> [...]

Schaltsekunden landen beispielsweise bei der MESZ regelmäßig
auf 01:59:60.

Tim
0 new messages