Discussion:
SQL Anfaengerfrage
(zu alt für eine Antwort)
Nicole Wagner
2011-02-11 09:45:59 UTC
Permalink
Hallo User,


ich habe eine SQL Anfaengerfrage, bei der ich nicht sicher bin, womit
ich sie am besten loese: Sort, Group, Having, First 3, eine Procedur?

Ich moechte dies tun:

- eine select Abfrage
- deren Ergebnis soll nach Kriterium 1 gelistet werden
- innerhalb jeder einzelnen Kriterium-1-Gruppe will ich die 3 maximalen
Werte des jeweiligen Kriterium-2.

Relevant ist, dass das Ergebnis keine Aggregatfunktion sein soll, die
mir z.B. eine Zusammenfassung gibt, sondern die komplette Tabelle. Es
soll also etwa so aussehen.

"Var":
Blusen: Select-Ergebnis
Farbe: Kriterium-1
Preis: Krietrium-2

Output:
Blusen gelb 30 uvam
Blusen gelb 20 uvam
Blusen gelb 10 uvam

Blusen blau 80 uvam
Blusen blau 50 uvam
Blusen blau 30 uvam

Alle Blusen < die 3 Maximalpreise pro Farbe brauche ich nicht.


Nicole
Thomas G. Liesner
2011-02-11 15:50:30 UTC
Permalink
Post by Nicole Wagner
Relevant ist, dass das Ergebnis keine Aggregatfunktion sein soll, die
mir z.B. eine Zusammenfassung gibt, sondern die komplette Tabelle. Es
soll also etwa so aussehen.
Blusen: Select-Ergebnis
Farbe: Kriterium-1
Preis: Krietrium-2
Blusen gelb 30 uvam
Blusen gelb 20 uvam
Blusen gelb 10 uvam
Blusen blau 80 uvam
Blusen blau 50 uvam
Blusen blau 30 uvam
Alle Blusen < die 3 Maximalpreise pro Farbe brauche ich nicht.
Ungetestet, bzgl. des limit ggf. Anpassung an konkrete DB nötig:

Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc

So long,
Thomas G. Liesner
Nicole Wagner
2011-02-11 18:14:53 UTC
Permalink
Post by Thomas G. Liesner
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc
Wow danke!
Das sieht elegant und vielversprechend aus.
Mache mich dann mal ans Testen.


Nicole
Nicole Wagner
2011-02-17 14:58:59 UTC
Permalink
Post by Thomas G. Liesner
Post by Nicole Wagner
Relevant ist, dass das Ergebnis keine Aggregatfunktion sein soll,
die mir z.B. eine Zusammenfassung gibt, sondern die komplette
Tabelle. Es soll also etwa so aussehen.
Blusen: Select-Ergebnis
Farbe: Kriterium-1
Preis: Krietrium-2
Blusen gelb 30 uvam
Blusen gelb 20 uvam
Blusen gelb 10 uvam
Blusen blau 80 uvam
Blusen blau 50 uvam
Blusen blau 30 uvam
Alle Blusen < die 3 Maximalpreise pro Farbe brauche ich nicht.
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc
So long,
Thomas G. Liesner
Leider nein!
Der Praxistest ist fehlgeschlagen aus 2 Gründen:
1) Mein Firebird Dialekt 3 kennt kein "limit" beim Sortieren
2) es darf innerhalb der select-Anweisungsklammer kein order stehen.

Ich habe mit allen meinen Versuchen dies Problem:
Stets sehe ich die Limitierung auf 3 der Gesamtabfrage.
Ich hingegen will die 3-Limitierung angewandt auf die JEWEILIGE
Unterabfrage.

Hast Du noch eine Idee?
Jemand anderer?

Nicole
Joe Galinke
2011-02-17 15:30:36 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Post by Thomas G. Liesner
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc
Leider nein!
1) Mein Firebird Dialekt 3 kennt kein "limit" beim Sortieren
Dazu schrieb Thomas aber schon deutlich:
| zgl. des limit ggf. Anpassung an konkrete DB nötig:

Limit geht nicht, wofür steht es überhaupt? Finde heraus was LIMIT bei SQL
bedeutet und überlege was Du haben willst.

Du willst, zumindest haben Thomas und ich Dich so verstanden, jeweils die
ersten 3 Einträge der absteigend nach Preis sortierten Einträge. Wie wäre
es dann mit FIRST 3? Wenn Du das nachschlägst wirst Du herausfinden, dass
die Anweisung dafür SELECT FIRST x .... lautet.
Post by Nicole Wagner
2) es darf innerhalb der select-Anweisungsklammer kein order stehen.
Doch. Wenn es bei Dir nicht klappt, zeige Dein Statement.
Post by Nicole Wagner
Stets sehe ich die Limitierung auf 3 der Gesamtabfrage.
Ich hingegen will die 3-Limitierung angewandt auf die JEWEILIGE
Unterabfrage.
Deshalb steht LIMIT ja auch im Subselect, so soll es auch mit dem
anzuwendenden FIRST sein. Ich glaube immer noch, dass es so passt.

Man hat nicht den Eindruck, als habest Du Dir beim Ausprobieren viel Mühe
gegeben. Auch wenn dieser Eindruck Dir massiv Unrecht tut, solltest Du
bedenken welches Bild hier viele von Dir haben.



Gruß, Joe
--
Nicole Wagner
2011-02-17 16:48:00 UTC
Permalink
Post by Joe Galinke
Limit geht nicht, wofür steht es überhaupt? Finde heraus was LIMIT
bei SQL bedeutet und überlege was Du haben willst.
Wie soll ich das Deiner Meinung nach herausfinden?
In meinen Handbuechern in Zusammenhang mit Sort habe ich es nicht
gefunden. Mein SQL-Syntax-Pruefer sagt, er kennt das Wort nicht.
Bei Helen Borrie wird es nur unter "delimiter" gefunden.

In Google moechte ich "limit" lieber nicht eingeben ;-)
Post by Joe Galinke
Du willst, zumindest haben Thomas und ich Dich so verstanden, jeweils
die ersten 3 Einträge der absteigend nach Preis sortierten Einträge.
Wie wäre es dann mit FIRST 3? Wenn Du das nachschlägst wirst Du
herausfinden, dass die Anweisung dafür SELECT FIRST x .... lautet.
First 3 ist mir bekannt.
Das Problem ist, dass ich nicht die "first 3" der Abfrage haben
moechte, sondern die "first 3" jeder einzelnen Unterabfrage. Und zwar
"immer wieder".
Wohin in da first 3 am besten schreibe, das habe ich noch nicht
heraussen. Doch siehe unten.
Post by Joe Galinke
Post by Nicole Wagner
2) es darf innerhalb der select-Anweisungsklammer kein order stehen.
Doch. Wenn es bei Dir nicht klappt, zeige Dein Statement.
Das ist nicht auf meinem Mist gewachsen.
S. 149:
"Order by ist innerhalb einer Unterabfrage nicht zulaessig".
cit aus "SQL - Einstieg in SQL".
Genau dem Buch, das mir hier so dringend empfohlen wurde.
Es baut auf Firebird 1.5

Nachem Du aber so ueberzeugt warst, habe ich es noch mal probiert.
Ja, wird auch bei mir akzeptiert. Offenbar hatte ich etwas anderes
falsch gehabt, das die Fehlermeldung ausgeloest hat (siehe unten)
Post by Joe Galinke
Post by Nicole Wagner
Stets sehe ich die Limitierung auf 3 der Gesamtabfrage.
Ich hingegen will die 3-Limitierung angewandt auf die JEWEILIGE
Unterabfrage.
Deshalb steht LIMIT ja auch im Subselect, so soll es auch mit dem
anzuwendenden FIRST sein. Ich glaube immer noch, dass es so passt.
ich kann von der Syntax her Limit nicht ins Subselect schreiben.




Meine Versuche willst Du sehen?
Also das ist die Basismenge. Sie gibt mir in recht kurzer Zeit, was ich
gerne will:


select tbkurszeilen.fk_kontrakt as fk_kontrakt,
tbkontrakte.name_ as name_,
tbkontrakte.comm as comm,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.o as o,
tbkurszeilen.h as h,
tbkurszeilen.l as l,
tbkurszeilen.c as c,
tbkurszeilen.volume as volume,
tbkurszeilen.openinterest as openinterest,
tbkurszeilen.long_stop as long_stop,
tbkurszeilen.short_stop as short_stop,
tbkurszeilen.fk_trade as fk_trade,
tbkurszeilen.id_kurszeilen as id_kurszeilen,
tbkurszeilen.baco as baco,
tbkurszeilen.trflag as Tradeflag
from tbkurszeilen
join
tbkontrakte on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt
and tbkurszeilen.fk_jdatum = '15.9.2009' ;

(Vielleicht wirst Du Dich erinnern, dass Du mir in grauer Vorzeit
geraten hast, das Datum NICHT als Zahl zu speichern. Wie Du siehst,
habe ich es umgestellt auf Typ TDate. Ich bin sehr froh darueber.
Danke.)


Das Kriterium 1 ist comm (3. Zeile) und das Kriterium 2 openinterest
(10.Zeile).
Ich moechte von jeder Comm jene 3 Datensaetze mit den höchsten
openinterest-Werten.

Meine Versuche sind vermutlich grausam, weil die Abfragen ploetzlich
bis zu einige Minuten dauern. (Wie das? Ich dachte, ich wuerde nur
innerhalb meiner ersten Untermenge suchen? Die umfasst vielleicht 100
Saetze)

Hier einer meiner Versuche:
.....
where comm in (select first 3 openinterest from tbkurszeilen order by
comm);

Dauert ewig und verursacht einen "Overflow".


Nicole
Joe Galinke
2011-02-17 20:56:48 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Wie soll ich das Deiner Meinung nach herausfinden?
In meinen Handbuechern in Zusammenhang mit Sort habe ich es nicht
gefunden. Mein SQL-Syntax-Pruefer sagt, er kennt das Wort nicht.
Bei Helen Borrie wird es nur unter "delimiter" gefunden.
In Google moechte ich "limit" lieber nicht eingeben ;-)
Natürlich nicht einfach nur "limit". Ich habe "firebird limit" als ersten
Versuch verwendet und hätte ggf. weitere Eingrenzungen versuchen können.
Das war aber nicht nötig, da das erste Suchergebnis, mit anderen Worten der
oberste Eintrag all meiner ca. 952.000 Ergebnisse die Antwort brachte. Das
auch noch in oberen Bildschirmhälfte jener Seite. Glaubst Du nicht, es ist
durchaus einen Versuch wert Google einzusetzen?

Sicher klappt das nicht immer so gut udn man kann auch schnell etwas
hilfreiches übersehen. Aber die Idee einen Allgemeinbegriff einzugrenzen
sollte man schon haben. Warum ich die beiden Begriffe kombiniert habe,
obwohl doch Firebird LIMIT nicht kennt? Na, weil ich nicht einzigartig bin
und andere sicherlich schon vor ähnlichen Problemen standen.
Post by Nicole Wagner
First 3 ist mir bekannt.
Das Problem ist, dass ich nicht die "first 3" der Abfrage haben
moechte, sondern die "first 3" jeder einzelnen Unterabfrage. Und zwar
"immer wieder".
Wohin in da first 3 am besten schreibe, das habe ich noch nicht
heraussen. Doch siehe unten.
In welchem Teil von Thomas Statement steht LIMIT? Richtig, im Subselect,
der untergeordneten Abfrage. Wie wäre es damit, FIRST genau dort
einzusetzen. Aber, wie ich bereits schrieb, nicht nach dem ORDER .. DESC,
sondern direkt nach dem SELECT.
Post by Nicole Wagner
Das ist nicht auf meinem Mist gewachsen.
"Order by ist innerhalb einer Unterabfrage nicht zulaessig".
cit aus "SQL - Einstieg in SQL".
Genau dem Buch, das mir hier so dringend empfohlen wurde.
Es baut auf Firebird 1.5
Vielleicht ging es nicht in Version 1.5, vielleicht ist die Aussage hier
falsch. Aber selbst dann wäre die Empfehlung nicht zwangsläufig falsch.
Post by Nicole Wagner
Post by Joe Galinke
Post by Nicole Wagner
Stets sehe ich die Limitierung auf 3 der Gesamtabfrage.
Ich hingegen will die 3-Limitierung angewandt auf die JEWEILIGE
Unterabfrage.
Deshalb steht LIMIT ja auch im Subselect, so soll es auch mit dem
anzuwendenden FIRST sein. Ich glaube immer noch, dass es so passt.
ich kann von der Syntax her Limit nicht ins Subselect schreiben.
Meine Versuche willst Du sehen?
Also das ist die Basismenge. Sie gibt mir in recht kurzer Zeit, was ich
select tbkurszeilen.fk_kontrakt as fk_kontrakt,
tbkontrakte.name_ as name_,
tbkontrakte.comm as comm,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.o as o,
tbkurszeilen.h as h,
tbkurszeilen.l as l,
tbkurszeilen.c as c,
tbkurszeilen.volume as volume,
tbkurszeilen.openinterest as openinterest,where farbe=bl.farbe
tbkurszeilen.long_stop as long_stop,
tbkurszeilen.short_stop as short_stop,
tbkurszeilen.fk_trade as fk_trade,
tbkurszeilen.id_kurszeilen as id_kurszeilen,
tbkurszeilen.baco as baco,
tbkurszeilen.trflag as Tradeflag
from tbkurszeilen
join
tbkontrakte on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt
and tbkurszeilen.fk_jdatum = '15.9.2009' ;
Das Kriterium 1 ist comm (3. Zeile) und das Kriterium 2 openinterest
(10.Zeile).
Entsprechend Deinem ersten Beispiel wäre comm die Farbe und openinterest
der Preis?
Post by Nicole Wagner
Meine Versuche sind vermutlich grausam, weil die Abfragen ploetzlich
bis zu einige Minuten dauern. (Wie das? Ich dachte, ich wuerde nur
innerhalb meiner ersten Untermenge suchen? Die umfasst vielleicht 100
Saetze)
Nein, lies Thomas Beispiel nochmal genauer.
Das Ergebnis ließ also lange auf sich warten, war es denn wenigstens
korrekt? Du solltest schon versuchen zu trennen. Zuerst einmal sollte das
Ergebnis stimme, dann die benötigte Zeit akzeptabel sein. Andersum an die
Sache heranzugehen ist unsinnig.
Post by Nicole Wagner
.....
where comm in (select first 3 openinterest from tbkurszeilen order by
comm);
Dauert ewig und verursacht einen "Overflow".
Hier nehme ich an, es kam auch kein brauchbares Ergebnis heraus. Bitte, sei
ein wenig präziser. Nebenbei wäre es einfacher, Du würdest das Statement
komplett hinschreiben. Zur Vereinfachung, auch bei deinen Tests, kannst Du
dafür ja einige Spalten weglassen.

Dein hier gezeigtes Beispiel auf das Ausgangsbeispiel umgesetzt würde
lauten:

where Farbe in (select first 3 Preis from tbkurszeilen order by
Farbe;

Aber Du hast die Lösung auch nicht richtig umgesetzt.

Thomas schrieb (hier auf die Verwendung von FIRST geändert):

where id in
(select FIRST 3 id from blusen where farbe=bl.farbe
order by preis desc)

ID ist die Primärschlüsselspalte Deiner Tabelle. Du aber hast das erste
Vorkommen von ID durch Dein erstes Kriterium ersetzt, das zweite durch Dein
drittes Kriterium. Außerdem hat Thomas Subselect noch eine Eingrenzung in
"where farbe=bl.farbe". Im Subselect wird auf bl.Farbe zugegriffen, den
Wert aus dem übergeordneten Select. Du müsstest in Deiner Where-Klausel die
Tabelle "veraliasen". Am besten sowohl mit einem Alias im übergeordneten
Select und einem ANDEREN Alias im Subselect.

Zurück nach IBExpert und ausprobieren.


Gruß, Joe
--
Nicole Wagner
2011-02-18 18:58:55 UTC
Permalink
Post by Nicole Wagner
select tbkurszeilen.fk_kontrakt as fk_kontrakt,
Post by Nicole Wagner
tbkontrakte.name_ as name_,
tbkontrakte.comm as comm,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.o as o,
tbkurszeilen.h as h,
tbkurszeilen.l as l,
tbkurszeilen.c as c,
tbkurszeilen.volume as volume,
tbkurszeilen.openinterest as openinterest,where
farbe=bl.farbe tbkurszeilen.long_stop as long_stop,
tbkurszeilen.short_stop as short_stop,
tbkurszeilen.fk_trade as fk_trade,
tbkurszeilen.id_kurszeilen as id_kurszeilen,
tbkurszeilen.baco as baco,
tbkurszeilen.trflag as Tradeflag
from tbkurszeilen
join
tbkontrakte on tbkurszeilen.fk_kontrakt =
tbkontrakte.id_kontrakt and tbkurszeilen.fk_jdatum =
'15.9.2009' ;
.....
where comm in (select first 3 openinterest from tbkurszeilen
order by comm);
(fuer hier Mitlesende: Ich moechte aus der ersten Menge die 3 jeweils
groessten openinterest Werte fuer je einzelne Comm ausgeben)
Post by Nicole Wagner
Bitte, sei ein wenig präziser. Nebenbei wäre es einfacher, Du würdest
das Statement komplett hinschreiben. Zur Vereinfachung, auch bei
deinen Tests, kannst Du dafür ja einige Spalten weglassen.
Mein Statement IST komplett hingeschrieben:
Der obere Teil ist die funktionierende Selektion.
Der Satz "einer meiner Versuche" die Fortsetzung davon, die nicht mehr
funktioniert.

Ich habe grundsaetzlich ein Problem.
Jeder meiner falschen Versuche kostet mich rund 10-15 Minuten pro Klick.
Weil meine Kiste haengen bleibt. Ich will meine Abfrage verarbeiten und
nicht tagelang dran rumbasteln. :-(((

Erstmals wird mir danach eine Fehlermeldung ausgegeben, sie lautet:

"The curser identified in the update or delete statement is not
positioned on a row. no current record for fetch operation."

Das kann ich zwar muehsam uebersetzen, doch beheben leider nicht.
Post by Nicole Wagner
Dein hier gezeigtes Beispiel auf das Ausgangsbeispiel umgesetzt würde
where Farbe in (select first 3 Preis from tbkurszeilen order by
Farbe;
Aber Du hast die Lösung auch nicht richtig umgesetzt.
where id in
(select FIRST 3 id from blusen where farbe=bl.farbe
order by preis desc)
ID ist die Primärschlüsselspalte Deiner Tabelle. Du aber hast das
erste Vorkommen von ID durch Dein erstes Kriterium ersetzt, das
zweite durch Dein drittes Kriterium. Außerdem hat Thomas Subselect
noch eine Eingrenzung in "where farbe=bl.farbe". Im Subselect wird
auf bl.Farbe zugegriffen, den Wert aus dem übergeordneten Select. Du
müsstest in Deiner Where-Klausel die Tabelle "veraliasen". Am besten
sowohl mit einem Alias im übergeordneten Select und einem ANDEREN
Alias im Subselect.
ich komme und komme nicht weiter
und bin am Verzeifeln:

Thomas schrieb das:
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc

1) Ich scheitere schon in der ersten Zeile bei "b1".
Das wird mir nicht akzeptiert. Sobald ich nach dem Tabellennamen ein
Alias schreibe, spuckt der Compiler die seltsamsten Fehlermeldungen.

2) Select in der Klammer erzeugt bei mir den 10 Minuten Haenger

3) Limit mit Firebird in Google eingegeben, bringt fast 1 Mio Treffer,
die offenbar darueber diskutieren, wie man einen Workaround
zusammenbringt.
Ich habe auch nach vielen Artikeln nicht verstanden, wie man das macht.
Vielleicht liegt es auch daran, dass ich schon das Beispiel Thomas
nicht auf meine Query analog umlegen kann.


Gibt es keinen Weg ohne Limit?


Oder koennte mir jemand ganz konkret eine Formulierung vorschlagen? Ich
komme mit meinen eigenen Blusen nicht zurecht. Ich benutze Firebird 2.1.


Nicole
Günter Kieninger
2011-02-19 16:03:06 UTC
Permalink
Post by Nicole Wagner
1) Ich scheitere schon in der ersten Zeile bei "b1".
Ich lese da zwar bl aber b1 müsste auch gehen.
Post by Nicole Wagner
Das wird mir nicht akzeptiert. Sobald ich nach dem Tabellennamen ein
Alias schreibe, spuckt der Compiler die seltsamsten Fehlermeldungen.
Der Compiler? Dem ist doch SQL sowas von wurscht. Und selbst die
seltsamsten Fehlermeldungen können genau gelesen viel verraten.
Es stellt sich die Frage Wer (Compiler oder Datenbank) sagt was genau?
Post by Nicole Wagner
2) Select in der Klammer erzeugt bei mir den 10 Minuten Haenger
Dann würde ich mal schauen ob die DB entsprechend optimiert ist (Index)

Gruß aus den Bergen
Günter
Nicole Wagner
2011-02-19 16:47:03 UTC
Permalink
Post by Günter Kieninger
Post by Nicole Wagner
1) Ich scheitere schon in der ersten Zeile bei "b1".
Ich lese da zwar bl aber b1 müsste auch gehen.
Post by Nicole Wagner
Das wird mir nicht akzeptiert. Sobald ich nach dem Tabellennamen ein
Alias schreibe, spuckt der Compiler die seltsamsten Fehlermeldungen.
Es ist egal, was bei mir nicht geht, ob b1 oder bl.
Es geht einfach nicht in meiner Query, an dieser Stelle ein Alias
einzufügen. (MEINE Query siehe oben)
Post by Günter Kieninger
Der Compiler? Dem ist doch SQL sowas von wurscht. Und selbst die
seltsamsten Fehlermeldungen können genau gelesen viel verraten.
Es stellt sich die Frage Wer (Compiler oder Datenbank) sagt was genau?
Ich geben meine SQL Query vorerste via IBExpert in die DB ein.
Diese Eingabe wird nicht akzeptiert, sobald ich an dieser Stelle ein
Alias schreibe.
Ob das Wort Compiler dabei korrekt ist, weiss ich nicht.
Post by Günter Kieninger
Post by Nicole Wagner
2) Select in der Klammer erzeugt bei mir den 10 Minuten Haenger
Dann würde ich mal schauen ob die DB entsprechend optimiert ist (Index)
Vielleicht kannst Du mal schauen, was in der Fehlermeldung steht, die
ich zitiert habe. Hat mit Sicherheit nichts mit Index zu tun.

Die DB ist ok. Es klappt ja auch die Query wunderbar. Nur die
Select-Fortsetzung nicht.



GROSSE BITTE:
Ihr schreibt hier sehr viel Text her und viele Fragen, die eigentlich
schon in der Thread stehen.

Die Loesung sollte maximal zwei Zeilen sein.
Wenn Ihr die Loesung wisst, koenntet Ihr nicht uns allen sehr viel
Arbeit ersparen und sie einfach hintippen?
Firebird 2.1. Der Query 1. Teil steht oben und er laeuft. Gesucht wird
der 2.Teil.


Nicole
Peter Lange
2011-02-19 19:08:55 UTC
Permalink
Post by Nicole Wagner
Ihr schreibt hier sehr viel Text her und viele Fragen, die eigentlich
schon in der Thread stehen.
Die Loesung sollte maximal zwei Zeilen sein.
Wenn Ihr die Loesung wisst, koenntet Ihr nicht uns allen sehr viel
Arbeit ersparen und sie einfach hintippen?
hier meine 2 Zeilen:

Hör' auf zu nerven,
setz' Dich hin und lerne!

Peter
Günter Kieninger
2011-02-19 20:03:12 UTC
Permalink
Post by Nicole Wagner
Die Loesung sollte maximal zwei Zeilen sein.
42

:)

Gruß aus den Bergen
Günter
Nicole Wagner
2011-02-21 14:07:15 UTC
Permalink
42
:)
das habe ich probiert:

ImprobabilityDrive:=ABSOLUTE;
SQL.Text:='42';

Aber es hat nicht geklappt. Ich habe sogar ein Handtuch ueber den
Schirm gelegt.


Nicole
Günter Kieninger
2011-02-22 08:03:28 UTC
Permalink
Post by Nicole Wagner
SQL.Text:='42';
42 ist nicht der Befehl sondern die Antwort.

Gruß aus den Bergen
Günter
Nicole Wagner
2011-02-22 11:37:19 UTC
Permalink
Post by Günter Kieninger
Post by Nicole Wagner
SQL.Text:='42';
42 ist nicht der Befehl sondern die Antwort.
Ja, normalerweise!
Doch ich habe ja vorher den Unwahrscheinlichkeits-Drive eingeschaltet.

Es sollte ja die Antwort auf meine Frage sein, wie meine (SQL-An)-frage
lautet. Daher ist Frage und Antwort ident. Nicht normal, aber sobald
der Unwahrscheinlichkeitsdrive aktiviert ist. ;-)


Nicole
Thomas G. Liesner
2011-02-19 21:21:53 UTC
Permalink
Post by Nicole Wagner
Wenn Ihr die Loesung wisst, koenntet Ihr nicht uns allen sehr viel
Arbeit ersparen und sie einfach hintippen?
BTW: Du kannst mich auch gerne für meine Zeit bezahlen, dann musst du
auch nicht mehr denken. Sooo hoch ist mein Stundensatz jetzt auch nicht.

So long,
Thomas G. Liesner
Joe Galinke
2011-02-21 09:25:46 UTC
Permalink
Dieser beitrag ist möglicherweise unangemessen. Klicken sie auf, um es anzuzeigen.
Thomas G. Liesner
2011-02-19 18:14:29 UTC
Permalink
Post by Nicole Wagner
1) Ich scheitere schon in der ersten Zeile bei "b1".
Das wird mir nicht akzeptiert. Sobald ich nach dem Tabellennamen ein
Alias schreibe, spuckt der Compiler die seltsamsten Fehlermeldungen.
Dann prüfe das erst mal an einem Einfacgbeispiel a la

select tab.text from tabelle tab

bzw.

select tab.text from tabelle as tab

Solange deine subquery ohne limit und filter läuft, hat sie noch eh
keinen sinn.

Nächster Test: "limit"

select first 3 text from tabelle

Und wenn die Sachen klappen, kannst du dich ja mal wieder am Gesamtwerk
versuchen, ansonsten mal die Fehlermeldungen nennen.
Post by Nicole Wagner
Gibt es keinen Weg ohne Limit?
Nicht bei deinen Anforderungen. Allerdings heisst es bei deiner DB eben
auch nicht limit.
Post by Nicole Wagner
Oder koennte mir jemand ganz konkret eine Formulierung vorschlagen? Ich
komme mit meinen eigenen Blusen nicht zurecht. Ich benutze Firebird 2.1.
Etwas Eigenarbeit schadet wirklich nicht.

So long,
Thomas G. Liesner
Joe Galinke
2011-02-21 09:11:33 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Ich habe grundsaetzlich ein Problem.
Jeder meiner falschen Versuche kostet mich rund 10-15 Minuten pro Klick.
Weil meine Kiste haengen bleibt. Ich will meine Abfrage verarbeiten und
nicht tagelang dran rumbasteln. :-(((
Nimmst Du wahr, dass man hier versucht Dir zu helfen?
Post by Nicole Wagner
"The curser identified in the update or delete statement is not
positioned on a row. no current record for fetch operation."
Das kann ich zwar muehsam uebersetzen, doch beheben leider nicht.
Ich habe Deine Tabelle nicht und arbeite deshalb "trocken". Dabei kann ich
auch gut Sachen übersehen und muss manchmal raten. Eine Vermutung äußere
ich weiter unten.
Post by Nicole Wagner
ich komme und komme nicht weiter
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc
1) Ich scheitere schon in der ersten Zeile bei "b1".
Es heißt bl mit _L_udwig, aber das ist technisch nicht wichtig.
Zeige bitte das Statement mit nicht akzeptiertem Alias.
Post by Nicole Wagner
Das wird mir nicht akzeptiert. Sobald ich nach dem Tabellennamen ein
Alias schreibe, spuckt der Compiler die seltsamsten Fehlermeldungen.
Bei Dir dürfte er, wenn ich richtig gezählt habe, erst in Zeile 17
auftauchen, nach "from tbkurszeilen".
Post by Nicole Wagner
2) Select in der Klammer erzeugt bei mir den 10 Minuten Haenger
Ich vermute lediglich, dass es damit zusammenhängt, dass Du das
Beispiel-SELECT von Thomas falsch umgesetzt hast. Auch das schrieb ich
bereits, erkenne aber keinerlei Reaktion von Dir auf meinen Hinweis.

| Aber Du hast die Lösung auch nicht richtig umgesetzt.
|
| Thomas schrieb (hier auf die Verwendung von FIRST geändert):
|
| where id in
| (select FIRST 3 id from blusen where farbe=bl.farbe
| order by preis desc)
|
| ID ist die Primärschlüsselspalte Deiner Tabelle. Du aber hast das
| erste Vorkommen von ID durch Dein erstes Kriterium ersetzt, das
| zweite durch Dein drittes Kriterium. Außerdem hat Thomas Subselect
| noch eine Eingrenzung in "where farbe=bl.farbe". Im Subselect wird
| auf bl.Farbe zugegriffen, den Wert aus dem übergeordneten Select. Du
| müsstest in Deiner Where-Klausel die Tabelle "veraliasen". Am besten
| sowohl mit einem Alias im übergeordneten Select und einem ANDEREN
| Alias im Subselect.


Welche Spalte ist der Primärschlüssel Deiner Tabelle? Es ist doch nicht
"comm", denke ich.

Wenn Du weiter Interesse an einer Lösung hast, so nimm doch bitte mal
hierzu Stellung. Ich muss Dich nicht damit nerven. Sags und ich höre auf.

Falls nicht, dann reduziere bitte Dein Statement um die Spalten die für die
eigentliche Problematik nicht benötigt werden, das macht es
übersichtlicher. Bitte zeige die Statements auch hier, dann muss man nicht
raten, wo Du den Alias hingesetzt hast.
Post by Nicole Wagner
tbkurszeilen.o as o,
tbkurszeilen.h as h,
tbkurszeilen.l as l,
tbkurszeilen.c as c,
tbkurszeilen.long_stop as long_stop,
tbkurszeilen.short_stop as short_stop,
tbkurszeilen.fk_trade as fk_trade,
tbkurszeilen.id_kurszeilen as id_kurszeilen,
tbkurszeilen.baco as baco,
tbkurszeilen.trflag as Tradeflag
Auch hast Du, glaube ich, meine Frage
| Entsprechend Deinem ersten Beispiel wäre comm die Farbe und openinterest
| der Preis?
nicht beantwortet. Ich habe sie hiermit wiederholt und bitte um
Beantwortung.
Post by Nicole Wagner
3) Limit mit Firebird in Google eingegeben, bringt fast 1 Mio Treffer,
die offenbar darueber diskutieren, wie man einen Workaround
zusammenbringt.
Genau. Der _ERSTE_ Treffer bietet die Lösung:
| SELECT FIRST x [SKIP y] ... [rest of query]

Das schrieb ich aber bereits.
Post by Nicole Wagner
Gibt es keinen Weg ohne Limit?
Warum verwendest Du noch diesen Begriff, wenn doch schon länger klar ist,
dass Du bei Firebird FIRST verwenden musst?



Gruß, Joe
--
Nicole Wagner
2011-02-21 11:49:25 UTC
Permalink
Hallo Leute,


danke fuer alle Antworten.
Vielleicht ist die Frage doch komplexer, als ich gehofft hatte:
Ich sehe mich mit den erhaltenen Antworten nicht heraus und kann weder
herauslesen, wo ich nachschlagen koennte, noch, wie die Loesung lautet.
Ich formuliere die Frage vielleicht neu.

@Thomas: Dein Beispiel kann ich nicht analog anwenden, weil ich nicht
mal von der Syntax hinkomme. Ohne Alias und ohne Limit kann es nicht
mehr gehen oder?

Vielleicht liegt die Sache auch mit dem join komplexer?



Hier noch mal meine Query auf das Notwendige reduziert.
Primaerschluessel hatte ich keinen abgefragt. Brauche ich denn den
unbedingt?

Ich schreibe die Abfrage fuer den PK in Kommentar dazu:

select tbkurszeilen.fk_kontrakt as fk_kontrakt,
/* der Primäschlüssel lautete: id_kurszeilen, */
tbkontrakte.comm as comm,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
from tbkurszeilen /* hier kann ich kein Alias einfügen ! */
join
tbkontrakte on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt
and tbkurszeilen.fk_jdatum = '15.9.2009' ;

SUBSELECT SOLL SEIN:
von dieser Abfrage will ich die ERSTEN drei Werte JEWEILS zu den
verschiedenen Comm-Treffern haben. Hierbei brauche ich also open
interest von der ersten Tabelle (JE drei Treffer) und Comm (zu ALLEN
Comm) von der join-Tabelle.

@Joe: wie ich das mit First und Skip loesen kann, weiss ich nicht. Denn
ich will ja nicht die ersten 3 Treffer insgesamt haben, sondern JEWEILS
zu JEDER Comm. Alle meine Versuche mit First haben leider nur INSGESAMT
drei Datensaetze ausgegeben.


=========================================

hier ist noch ein stark verkürztes Beispiel (ohne join!), bei dem
zweifach der Wurm drinnen ist:
1) Es rechnet mit dem 2. Select minutenlang. Warum nur?
2) Es gib nur INSGESAMT 3 Ergebnisse statt 3 pro Comm:

Select tbkontrakte.name_,
tbkontrakte.id_kontrakt as id
from tbkontrakte
where tbkontrakte.id_kontrakt in
(select first 3 tbkontrakte.id_kontrakt from tbkontrakte where
comm=tbkontrakte.comm order by name_ desc)

gibt:

NAME_ ID
YUZ9 7.786
YUZ9 7.826
YUZ9 8.062


Nicole
Joe Galinke
2011-02-21 15:45:30 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Hier noch mal meine Query auf das Notwendige reduziert.
Primaerschluessel hatte ich keinen abgefragt. Brauche ich denn den
unbedingt?
Du brauchst etwas, das den Datensatz eindeutig identifiziert, der PK ist
doch wunderbar dafür geeignet. Warum fragst Du, ob Du ihn unbedingt
brauchst, was hält Dich davon ab? Er muss auch nicht als Spalte mit
aufgeführt werden, aber im WHERE.

Nochmal Thomas Beispiel:

| where id in
| (select id from blusen where farbe=bl.farbe

id ist die Spalte mit dem PK.


Ganz nebenbei. Ich habe in meinem Posting eine Frage wiederholt, auf die Du
noch immer nicht geantwortet hast. Hat das einen bestimmten Grund? Soll ich
sie einfach 6 Mal hintereinander in das Posting hier einfügen?

Ebenso reagierst Du nicht darauf, dass Du scheinbar Thomas Beispiel falsch
umgesetzt hast. Auch hier frage ich, ob es einen bestimmten Grund dafür
gibt.
Post by Nicole Wagner
select tbkurszeilen.fk_kontrakt as fk_kontrakt,
/* der Primäschlüssel lautete: id_kurszeilen, */
tbkontrakte.comm as comm,
Demnach brauchen wir die PK-Spalte von tbkontrakte weil in der
WHERE-Klausel mit dem Subselect (dem SELECT in Klammern) auf die Datensätze
von tbkontrakte reduziert werden soll die dem Suchkriterium comm
entsprechen.

Ich muss aber sagen, dass ich mich durch Dein tb-Präfix habe verwirren
lassen. comm ist eine Spalte aus tbkontrakte, nicht tbkurszeilen. Da war
ich schlichtweg blind. Sorry.

Demnach brauchst Du den Alias im JOIN.

JOIN tbkontrakte KON_MAIN on....

Allerdings liegen Deine Kriterien, wie ich verspätet erkenne, in
verschiedenen Tabellen. Das lässt mich glauben, dass das Subselect auch
einen JOIN braucht. Ganz trocken, ohne passende Tabellen zum Ausprobieren
verlaufe ich mich durchaus gerne mal. Wenn hier anschließend Unsinn
formuliert wird nehme ich Kritik und Hinweise gerne entgegen. Ich bin sogar
sicher, dass es teilweise Blödsinn sein wird.

WHERE KON_MAIN.id_kontrakt in
(SELECT FIRST 3 KON_SUB.id_kontrakt
FROM tbkontrakte KON_SUB
LEFT JOIN tbkurszeilen KURSZ_SUB ON
(KURSZ_SUB.fK_kontrakt=KON_SUB.id_kontrakt)
WHERE KON_SUB.comm=KON_MAIN.comm ORDER BY KURSZ_SUB.openinterest DESC)


Ich will mich nicht herausreden, aber evtl. wäre es mir eher aufgefallen,
wenn das Statement von Anfang an auf die wirklich relevanten Sachen
reduziert worden wäre. Natürlich hättest Du dann auch nur mit diesem
reduzierten Statement testen dürfen.

Wenn Du das also ausprobieren möchtest, dann nimmst Du zuerst dein
reduziertes Statement ohne

KON_MAIN.id_kontrakt in
(SELECT ..... DESC)

Dann siehst Du, ob Dein Alias selbst keinen Fehler verursacht.

Als 2. Test nimmst Du das Subselect aus der Klammer ohne

WHERE KON_SUB.comm=KON_MAIN.comm
Wenn das nicht durchläuft kann das gesamte Statement auch nicht
funktionieren.

Nochmal: Es ist recht wahrscheinlich, dass hier wegen Trockenlaufs noch
Fehler drinstecken.
Post by Nicole Wagner
hier ist noch ein stark verkürztes Beispiel (ohne join!), bei dem
1) Es rechnet mit dem 2. Select minutenlang. Warum nur?
Rechnet es minutenlang und hinterher passt das Ergebnis oder kommt dann ein
Fehler. Warum muss man Dir alles aus der Nase ziehen?

@ALL:
Sollte ich das falsch sehen nehme ich Hinweise gerne entgegen.

Wenn hinterher alles passt, dann muss man evtl. wirklich noch optimieren.
Siehe Günters Hinweis darauf. Stimmt das Ergebnis nicht oder kommt dann ein
Fehler, dann ist das Statement falsch und die Laufzeit als solche
interessiert (mich) nicht.



Gruß, Joe
--
Nicole Wagner
2011-02-21 18:00:55 UTC
Permalink
Post by Joe Galinke
Du brauchst etwas, das den Datensatz eindeutig identifiziert, der PK
ist doch wunderbar dafür geeignet. Warum fragst Du, ob Du ihn
unbedingt brauchst, was hält Dich davon ab?
.... nichts, ich fuege ihn ein.
Fuer beide Tabellen.
Post by Joe Galinke
Ganz nebenbei. Ich habe in meinem Posting eine Frage wiederholt,
...sorry, weil ich mich gar nicht mehr raussehe.
In SQL bin ich nicht sattelfest, die Syntax mit IN habe ich das erste
mal gesehen und sie schwirrt mir im Kopf. Ich weiss nicht mehr, was was
ist. Meine Versuche erstelle ich, indem ich Postings/Buecher ausdrucke
und mit rauchendem Kopf versuche, die richtigen Worte an den richtigen
Platz zu stellen.
Wenn Du mich dann nach dem SINN fragst, ... *erroet*
Post by Joe Galinke
Ebenso reagierst Du nicht darauf, dass Du scheinbar Thomas Beispiel
falsch umgesetzt hast. Auch hier frage ich, ob es einen bestimmten
Grund dafür gibt.
Klar gibt es den:
Ich bringe es nicht zusammen. Wie man es richtig umsetzt, weiss ich
nicht. Auch Deine Hinweise konnte ich nicht anwenden. Die Syntax fliegt
mir um die Ohren. Details unten.
Post by Joe Galinke
Ich muss aber sagen, dass ich mich durch Dein tb-Präfix habe verwirren
lassen. comm ist eine Spalte aus tbkontrakte, nicht tbkurszeilen. Da
war ich schlichtweg blind. Sorry.
Tut mir auch leid!
Ich habe erst in diesem Posting gesehen, wie AEHNLICH die beiden Zeilen
optisch aussehen und deshalb erst jetzt explizit darauf hingewiesen.
Post by Joe Galinke
Demnach brauchst Du den Alias im JOIN.
Der wird mir auch nicht genommen.

Ich setzte alle Fehlerversuche in Kommentar.
Wenn Du es mit Copy in Paste in IBExpert rueberholst, dann wird die
Schrift bunt und Du kannst schnell sehen, wo die Probleme liegen.
Post by Joe Galinke
Ich will mich nicht herausreden, aber evtl. wäre es mir eher
aufgefallen, wenn das Statement von Anfang an auf die wirklich
relevanten Sachen reduziert worden wäre.
Wenn mir von Anfang an klar waere, was wirklich relevant ist, dann
wuesste ich vermutlich auch die Loesung, ;-) Ich koennte sie mir
einfach aus Google holen. Dass der join hier so pestig wird, habe ich
z.B. nicht geahnt.
Ich bemuehe mich, die Leute hier nicht mit zu vielen Details zu
belaestigen und auch nicht zu wenig Infos herzugeben. Leider gelingt es
mir nur recht selten, die richtige Dosis zu erwischen.



Also hier einmal mein neuer Ansatz mit Fehlversuchen in Kommentar:


select tbkurszeilen.fk_kontrakt as fkkontrakt,
tbkontrakte.name_ as name_,
tbkontrakte.id_kontrakt as idkontrakt, /*NEU*/
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
tbkurszeilen.id_kurszeilen as idkurszeilen, /*NEU*/
tbkontrakte.comm as comm_
from tbkurszeilen
join
tbkontrakte /* "as kontrakte"
Alias Versuch erzeugt auch hier die Fehlermeldung:
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TBKONTRAKTE.ID_KONTRAKT.
At line 9, column 7 */
on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt

/* BEGINN SUBSELECT // also probiere ich es ohne alias */
where tbkontrakte.id_kontrakt in
(select first 3 idkontrakt from tbkontrakte
/* left join idkurszeilen on (tbkontrakte.id_kontrakt=fkkontrakt)*/
wir nicht genommen:
Undefined name.
Dynamic SQL Error.
SQL error code = -204.
Table unknown.
IDKURSZEILEN.
At line 25, column 30.
Ich probiere also eine andere Formulierung:
*/

/* left join tbkurszeilen.id_kurszeilen on
(tbkontrakte.id_kontrakt=fkkontrakt)
wird auch nicht genommen: Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 34, column 28.*/


where comm_=tbkontrakte.comm) /* order by noch weggelassen */


in diesem letzten where Statement kann ich auf comm gar nicht zugreifen.
Nicht mit comm, nicht mit tbkontrakte.comm, nicht mit tbkontrakte.comm_.
"unbekannt oder 'gehöert nicht zur Tabelle'.


Ich kann mit diesem Subselect-Statement auch ohne die auskommentierten
Zeilen keinerlei sinnvolles Ergebnis bekommen. Sondern ich sehe nur
Syntax-Fehlermeldungen. Sinnvoll wuerde es nur, wenn ich alles nach
"BEGINN SUBSELECT" weglasse und endete mit der Zeile:
"on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt"


Danke fuer Deine Muehe!
Ich bin fuer jeden neuen Versuch dankbar.



Nicole
Joe Galinke
2011-02-21 20:00:34 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
.... nichts, ich fuege ihn ein.
Fuer beide Tabellen.
Missverständnis. In der Ergebnismenge brauchen wir die Spalten nicht, da
habe ich mich unklar ausgedrückt.
Post by Nicole Wagner
In SQL bin ich nicht sattelfest, die Syntax mit IN habe ich das erste
mal gesehen und sie schwirrt mir im Kopf. Ich weiss nicht mehr, was was
ist. Meine Versuche erstelle ich, indem ich Postings/Buecher ausdrucke
und mit rauchendem Kopf versuche, die richtigen Worte an den richtigen
Platz zu stellen.
Nicht, dass ich es nicht verstünde, aber Du weißt, dass Du Dir damit
wirklich keinen Gefallen tust?
Post by Nicole Wagner
Ich bringe es nicht zusammen. Wie man es richtig umsetzt, weiss ich
nicht. Auch Deine Hinweise konnte ich nicht anwenden. Die Syntax fliegt
mir um die Ohren. Details unten.
Dann sag das doch. Dir wurde schon früher, auch von anderen, vorgeworfen,
dass Du Antworten auf Deine Fragen scheinbar gar nicht liest. Glaubst Du,
das motiviert zum Antworten?
Post by Nicole Wagner
Tut mir auch leid!
Ich habe erst in diesem Posting gesehen, wie AEHNLICH die beiden Zeilen
optisch aussehen und deshalb erst jetzt explizit darauf hingewiesen.
Ich selbst vermeide übrigens die Spezifizierung mit führendem
Tabellennamen. Dafür muss ich halt im Bedarfsfall Aliase verwenden, das
halte ich aber immer noch für lesbarer.
Post by Nicole Wagner
Post by Joe Galinke
Demnach brauchst Du den Alias im JOIN.
Der wird mir auch nicht genommen.
Ich setzte alle Fehlerversuche in Kommentar.
Wenn Du es mit Copy in Paste in IBExpert rueberholst, dann wird die
Schrift bunt und Du kannst schnell sehen, wo die Probleme liegen
Wenn mir von Anfang an klar waere, was wirklich relevant ist, dann
wuesste ich vermutlich auch die Loesung, ;-)
Nein. Ich meine eine Reduktion auf die Spalten die als Kriterien
interessant sind. Aber Du hast ja bereits zusammengestrichen.
Post by Nicole Wagner
Ich koennte sie mir einfach aus Google holen.
Das bezweifle ich.
Post by Nicole Wagner
select tbkurszeilen.fk_kontrakt as fkkontrakt,
tbkontrakte.name_ as name_,
tbkontrakte.id_kontrakt as idkontrakt, /*NEU*/
Wie schon oben gesagt, wir brauchen sie nicht in der Anzeige, also raus
damit.
Post by Nicole Wagner
tbkurszeilen.fk_jdatum as datum,
Für den Test IMHO nicht relevant, also raus.
Post by Nicole Wagner
tbkurszeilen.openinterest as openinterest,
tbkurszeilen.id_kurszeilen as idkurszeilen, /*NEU*/
Wie schon oben gesagt, wir brauchen sie nicht in der Anzeige, also raus
damit.
Post by Nicole Wagner
tbkontrakte.comm as comm_
Warum der Feldalias comm_?
Post by Nicole Wagner
from tbkurszeilen
join
tbkontrakte /* "as kontrakte"
Wer sagte was von "as"? :-)
Einfach tbkontrakte KON_MAIN

Ich habe übrigens ganz bewusst etwas wie KON_MAIN verwendet.
Einmal, weil etwas wie kontrakte zu sehr in den vielen tbkontrake
untergeht, zum Anderen weil das Suffix _MAIN, bzw. _SUB deutlich macht auf
welche Tabelle zugegriffen wird.
Post by Nicole Wagner
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TBKONTRAKTE.ID_KONTRAKT.
At line 9, column 7 */
Jetzt bin ich nicht sicher, ob diese Fehlermeldung bei Verwendung des "as"
auftrat. Im Moment sehe ich nämlich nicht was daran falsch sein sollte.
Post by Nicole Wagner
on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt
on tbkurszeilen.fk_kontrakt=KON_MAIN.id_kontrakt
//Ja, ich habe den Alias verwendet, nicht den Tabellennamen.
Post by Nicole Wagner
/* BEGINN SUBSELECT // also probiere ich es ohne alias */
where KON_MAIN.id_kontrakt in
(select first 3 KON_SUB.id_kontrakt from tbkontrakte KON_SUB
Die Aliase sind wieder drin.
Post by Nicole Wagner
/* left join idkurszeilen on (tbkontrakte.id_kontrakt=fkkontrakt)*/
Undefined name.
Dynamic SQL Error.
SQL error code = -204.
Table unknown.
IDKURSZEILEN.
Was sind idkurszeilen? Ich schrieb:
LEFT JOIN tbkurszeilen KURSZ_SUB ON
(KURSZ_SUB.fK_kontrakt=KON_SUB.id_kontrakt)
Post by Nicole Wagner
At line 25, column 30.
*/
/* left join tbkurszeilen.id_kurszeilen on
(tbkontrakte.id_kontrakt=fkkontrakt)
wird auch nicht genommen: Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 34, column 28.*/
fkkontrakt ist ein Feldalias. Nimm, wie bereits weiter oben,
KURSZ_SUB.fk_kontrakt.
Post by Nicole Wagner
where comm_=tbkontrakte.comm) /* order by noch weggelassen */
Ich schrieb mit Alias:
WHERE KON_SUB.comm=KON_MAIN.comm

Ich glaube immer noch, dass es zumindest richtiger ist als Deine Version.
Post by Nicole Wagner
Ich kann mit diesem Subselect-Statement auch ohne die auskommentierten
Zeilen keinerlei sinnvolles Ergebnis bekommen.
Hast Du das Subselect mal solo, unter Weglassung von
WHERE KON_SUB.comm=KON_MAIN.comm
ausgeführt?

Es müsste dann lauten:

SELECT FIRST 3 KON_SUB.id_kontrakt
FROM tbkontrakte KON_SUB
LEFT JOIN tbkurszeilen KURSZ_SUB ON
(KURSZ_SUB.fK_kontrakt=KON_SUB.id_kontrakt)

/* ausgeklammert WHERE KON_SUB.comm=KON_MAIN.comm */

ORDER BY KURSZ_SUB.openinterest DESC



Gruß, Joe
--
Joe Galinke
2011-02-22 10:23:02 UTC
Permalink
Hallo,
Post by Joe Galinke
Ich selbst vermeide übrigens die Spezifizierung mit führendem
Tabellennamen. Dafür muss ich halt im Bedarfsfall Aliase verwenden, das
halte ich aber immer noch für lesbarer.
Ich glaube, die Verwendung der voll qualifizierten Spaltenangaben beißt
sich mit einem evtl. Alias.

Deshalb solltest du statt

select tbkurszeilen.fk_kontrakt as fkkontrakt,
tbkontrakte.name_ as name_,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
tbkontrakte.comm as comm_

from tbkurszeilen
join tbkontrakte KON_MAIN ON
tbkurszeilen.fk_kontrakt=KON_MAIN.ID_KONTRAKT


folgendes Statement versuchen:

select tbkurszeilen.fk_kontrakt as fkkontrakt,
KON_MAIN.NAME_ as name_,
^^^^^^^^

tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
KON_MAIN.comm as comm_
^^^^^^^^

from tbkurszeilen
join tbkontrakte KON_MAIN ON
tbkurszeilen.fk_kontrakt=KON_MAIN.ID_KONTRAKT

Wenn ich Recht habe, dann musstest Du mit dem Alias gegen die Wand laufen.

Hättest Du auch einen Alias für tbkurszeilen, müssten auch die Spalten aus
dieser Tabelle mit dem Alias qualifiziert werden.


Gruß, Joe
--
Nicole Wagner
2011-02-22 10:46:17 UTC
Permalink
Post by Joe Galinke
Post by Nicole Wagner
Ich bringe es nicht zusammen. Wie man es richtig umsetzt, weiss ich
nicht. Auch Deine Hinweise konnte ich nicht anwenden. Die Syntax
fliegt mir um die Ohren. Details unten.
Dann sag das doch. Dir wurde schon früher, auch von anderen,
vorgeworfen, dass Du Antworten auf Deine Fragen scheinbar gar nicht
liest. Glaubst Du, das motiviert zum Antworten?
Ich bin hier teils reuig, weil ich so gierig nach der Loesung bin und
ungeduldig ueberfliege, was kommt.
Teils bin ich nicht reuig. Denn viele der Antwortenden lesen offenbar
die Fragen schludrig. Und ich verstehe das sogar sehr gut:

Wir leben alle in einer Zeit, wo die Texte foermlich ueber uns
zusammenschlagen. Wir kaempfen uns taeglich verzweifelt durch
seitenlangen Schrott, der um unsere Aufmerksamkeit buhlt und im Grunde
nur unsere Geldboerse meint. Wir sind sowieso "boese". Egal, ob wir
unsere Post nicht mehr lesen oder ob wir sie schlampig lesen.

Dieses Dilemma loesen viele mit einem Aufmerksamkeitsfilter: Sie
VERGESSEN. Die Verkaeuferin an der Fleischtheke, die hoert Dich voll.
Aber nach 2 Minuten kennt sie Dein Gesicht nicht mehr. Wenn die auf
feinfuehlig macht, ist sie nach 3 Monaten in der Irrenanstalt.

Reizueberflutung.
Ich "versage" eben auf meine Weise.
Post by Joe Galinke
Ich selbst vermeide übrigens die Spezifizierung mit führendem
Tabellennamen. Dafür muss ich halt im Bedarfsfall Aliase verwenden,
das halte ich aber immer noch für lesbarer.
Glaub mir, es ist Gewohnheit.
Mir hat man zu Beginn eingeredet, dass man unbedingt die Konvention
tbirgendwas verwenden muss. Amen.

Ich habe mich daran gewoehnt und fuer mich ist heute meine eigene
Gewohnheit lesbarer.

Sie hat ihren Vorteil objektiv vermutlich weniger in der Lesbarkeit,
als im Textvervollstaendigen. Ich weiss, dass ich nur tb eingeben muss,
um eine sofortige Listung aller meiner Tabellennamen zu erhalten.
Post by Joe Galinke
Post by Nicole Wagner
tbkontrakte.comm as comm_
Warum der Feldalias comm_?
Willst Du das wirklich wissen?!
ok, dann sage ich es Dir:
Comm ist grundsaetzlich mein Kurzwort fuer Commodity. Es sagt mir was,
wenn ich es lese.
Und der Unterstrich? - Beschwere Dich bitte bei der Mathe-Prof meiner
Schulzeit. Sie nannte alles Abgeleitete: "Name-Strich", damals mit
einem Hochkomma ausgedrueckt.
Daher ist der Alias fuer Commodity eben Comm_
Post by Joe Galinke
Post by Nicole Wagner
from tbkurszeilen
join
tbkontrakte /* "as kontrakte"
Wer sagte was von "as"? :-)
Also mein Lehrbuch sagt, dass Firebird as nicht braucht, aber es auch
nicht schadet, wenn man es verwendet.
Nachdem ich mich ohnehin schwertue, verwende ich es, weil es mir ein
Jota mehr "deutsche Sprache" vorgaukelt. Abgesehen davon, dass es
englisches Gestammel bleibt.
Post by Joe Galinke
Einfach tbkontrakte KON_MAIN
Ich habe übrigens ganz bewusst etwas wie KON_MAIN verwendet.
und jetzt steige ich leider aus.
Ich KANN es nicht verwenden.
Sobald ich das Wort hinschreibe, mit oder ohne as, spuckt IBExpert
diese seltsamen Fehlermeldungen, von denen ich einige zitierte. Ich
KANN keinen alias fuer einen Tabellennamen einsetzen. Nur fuer
Feldnamen.

Und das ist auch der Grund, warum ich die weiteren Dinge nicht umsetzen
konnte, wie etwas "KON_MAIN.id_kontrakt".
Es fehlt die Basis Kon_Main.

(abgesehen davon, dass ich im Kreis laufe und rufe: WARUM? Das sollte
doch gehen)


Weisst Du vielleicht einen Work-Around?
Ich moechte unbedingt eine SQL Abfrage schreiben, weil die direkt von
meinem DBGrid verarbeitet wird.

Ich habe es schon mit einer Procedur versucht. Doch auch hier bin ich
Anfaengerin. Ich konnte nur Output-Variablen erzeugen, die GENAU EINEN
Datensatz zum Ergebnis hatten.

Hat eine Procedur stets einzelne Var zum Ergebnis oder kann ich auch
ganze "Tabellen" als Ergebnis bekommen? Ich habe in der Literatur
nichts gefunden.


Nicole
Joe Galinke
2011-02-22 11:10:30 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Teils bin ich nicht reuig. Denn viele der Antwortenden lesen offenbar
die Fragen schludrig.
Es ist nur so, dass Du ein Problem lösen möchtest und es ja nicht nur um
diesen Thread geht.
Post by Nicole Wagner
Post by Joe Galinke
Ich selbst vermeide übrigens die Spezifizierung mit führendem
Tabellennamen. Dafür muss ich halt im Bedarfsfall Aliase verwenden,
das halte ich aber immer noch für lesbarer.
Glaub mir, es ist Gewohnheit.
Mir hat man zu Beginn eingeredet, dass man unbedingt die Konvention
tbirgendwas verwenden muss. Amen.
Ich sage auch nicht, dass Deine Vorgehensweise falsch ist.

Allerdings, siehe bitte mein anderes Posting von 11_32 Uhr mit Message-ID:
<***@mid.individual.net>, wüsste ich jetzt nicht wie die
vollständige Qualifikation über Tabellennamen mit Aliasen in Verbindung
bringen soll. Wenn ich in geschachtelten Statements mehrfach auf die
gleiche Tabelle zugreifen möchte, komme _ich_ ohne Alias nicht weiter,
kollidiere aber dann mit den vorangestellten Tabellennamen.
Post by Nicole Wagner
Post by Joe Galinke
Post by Nicole Wagner
tbkontrakte /* "as kontrakte"
Wer sagte was von "as"? :-)
Also mein Lehrbuch sagt, dass Firebird as nicht braucht, aber es auch
nicht schadet, wenn man es verwendet.
Du hast allerdings Recht, es schadet nicht. Da ich bisher, auch z.B. mit
Oracle darauf verzichten konnte hat es mich einfach als Abweichung von
meinem Vorschlag irritiert. Da ich die Abfragen, wie schon gesagt, nicht
ausführen sondern nur betrachten kann, war es einfach ein Störfaktor.
Post by Nicole Wagner
und jetzt steige ich leider aus.
Ich KANN es nicht verwenden.
Und, siehe besagtes anderes Posting, ich denke, ich weiß auch warum.



Gruß, Joe
--
Joe Galinke
2011-02-21 16:31:11 UTC
Permalink
Hallo Nicole,

ich habe noch etwas vergessen.
Post by Nicole Wagner
@Joe: wie ich das mit First und Skip loesen kann, weiss ich nicht.
Unter
| SELECT FIRST x [SKIP y] ... [rest of query]

steht aber noch
| and optionally skip first y rows.

Also lässt Du SKIP einfach weg, das brauchst Du hier nicht.
Post by Nicole Wagner
Select tbkontrakte.name_,
tbkontrakte.id_kontrakt as id
from tbkontrakte
where tbkontrakte.id_kontrakt in
(select first 3 tbkontrakte.id_kontrakt from tbkontrakte where
comm=tbkontrakte.comm order by name_ desc)
Einfach nur draufgeguckt (Irrtümer also gut möglich) fehlt hier der Alias.
Welches tbkontrakte ist denn jeweils gemeint?

Select tbkontrakte.name_,
tbkontrakte.id_kontrakt as id
from tbkontrakte KON_MAIN
where KON_MAIN.tbkontrakte.id_kontrakt in
(select first 3 KON_SUB.tbkontrakte.id_kontrakt
from tbkontrakte KON_SUB
where KON_SUB.comm=KON_MAIN.comm order by KON_SUB.name_ desc)


Wieso jetzt eigentlich name_? Sollte es nicht openinterest aus tbkurszeilen
sein?


Gruß, Joe
--
Nicole Wagner
2011-02-25 12:24:13 UTC
Permalink
ad "weil es nicht filtert"
(ich versuche stets an einer Front, ob ich weiterkomme)

Diese subselect-first-n-Abfrage tut bei mir nichts.
(bitte nur die beiden letzten Zeilen der Abfrage lesen)

select
tbkurszeilen_.fk_kontrakt as fk_kontrakt,
tbkontrakte_.name_ as name_,
tbkontrakte_.comm as comm,
tbkontrakte_.id_kontrakt as id_kontrakt,
tbkurszeilen_.fk_jdatum as datum,
tbkurszeilen_.o as o,
tbkurszeilen_.h as h,
tbkurszeilen_.l as l,
tbkurszeilen_.c as c,
tbkurszeilen_.volume as volume,
tbkurszeilen_.openinterest as openinterest,
tbkurszeilen_.long_stop as long_stop,
tbkurszeilen_.short_stop as short_stop,
tbkurszeilen_.fk_trade as fk_trade,
tbkurszeilen_.id_kurszeilen as id_kurszeilen,
tbkurszeilen_.baco as baco,
tbkurszeilen_.trflag as Tradeflag
from tbkurszeilen as tbkurszeilen_
join
tbkontrakte as tbkontrakte_
on tbkurszeilen_.fk_kontrakt = tbkontrakte_.id_kontrakt
and tbkurszeilen_.fk_jdatum = '15.9.2009'


where comm in (select first 1 comm from tbkontrakte)
/* gibt stets ALLE Datensätze EINER comm */

================================================================
d.h.
where comm in (select first 3 comm from tbkontrakte)
gibt mir 3 Datensaetze

where comm in (select first 1 comm from tbkontrakte)
gibt mir 3 Datensaetze

where comm in (select first 10 comm from tbkontrakte)
gibt mir 3 Datensaetze

Diese 3 Datensaetze sind alle jene, die zum Datum der ersten Ware
vorhanden sind.

Jetzt wird sich vielleicht bald einer an die Stirn schlagen, weil er im
Gegensatz zu mir verstanden hat, warum das so ist. Wie es aber
wunschgemaess geht, erscheint mir die zweite Stufe.

Auch das sub-select auf tbkurszeilen zu geben, bringt mir die KOMPLETTE
Abfrage und keine reduzierte.
Das sah mit dem join genauso aus (first n tat nichts), es hat nur
ungleich laenger gedauert als ohne join im subselect.



an der Dataset-Eventfront lese ich:
"aus der Datenmenge kann nichts gelöscht werden, keine Löschabfrage"
Aber dort kaempfe ich vorerst noch alleine.


Nicole
Joe Galinke
2011-02-25 12:43:08 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Diese subselect-first-n-Abfrage tut bei mir nichts.
(bitte nur die beiden letzten Zeilen der Abfrage lesen)
[ ... ]
Post by Nicole Wagner
where comm in (select first 1 comm from tbkontrakte)
Das kann doch auch gar nicht gehen. Das hat nichts mit der vorgeschlagenen
Abfrage zu tun.

Bitte, bitte, bitte, lies die jüngeren Postings dazu.
Nochmal? Ok.
Bitte!

Message-ID: <***@mid.individual.net> vom 24.02., 15:48 Uhr
und das folgende Posting.
Post by Nicole Wagner
"aus der Datenmenge kann nichts gelöscht werden, keine Löschabfrage"
Aber dort kaempfe ich vorerst noch alleine.
Du sollst doch auch nichts aus der Ergebnismenge löschen.
Löschen <> Filtern

Auch hierzu schrieb ich was im o.g. Posting und in
Message-ID: <***@mid.individual.net> vom 24.02., 18:17 Uhr.


Gruß, Joe
--
Nicole Wagner
2011-02-25 15:56:30 UTC
Permalink
Post by Joe Galinke
Bitte, bitte, bitte, lies die jüngeren Postings dazu.
Habe ich schon gestern. Und ausgedruckt. Und noch mal gelesen.
Wort fuer Wort von hinten nach vorne und von vorne nach hinten.
Ich habe alles so eingegeben, wie es drin stand. Und auch wie Du mir
nahegelegt hast, habe ich versucht, es zu durchdenken. Ich habe auch
viel gelernt dabei. Nur leider der Anlass ist ungeloest.

Es lief langsam, aber es lief.
Das Ergebnis war nur leider so, dass mehr als 3 Zeilen pro Comm
ausgegeben waren.

(In einem meiner Postings sollte der Volltext davon stehen.)
Post by Joe Galinke
Post by Nicole Wagner
"aus der Datenmenge kann nichts gelöscht werden, keine Löschabfrage"
Aber dort kaempfe ich vorerst noch alleine.
Du sollst doch auch nichts aus der Ergebnismenge löschen.
Löschen <> Filtern
Zu diesem Filter-Event finde ich rein gar nichts.
Nicht in der Hilfe, nicht in meinen 100te-Seiten IB-Dokumentationen,
nicht bei Google. Bei Google zumindest nichts, was ausfuehrlich genug
waere, dass ich genug verstehe, Datensatz-Zeilen zu loeschen.

Ist das Filter-Event eigentlich der Weg des geringsten Widerstandes?
Im Grunde moechte ich die Zeilen nur nicht im Grid sehen, weil es
zuviel wird. Gibt es im DBGrid etwas, das nur ausblendet und lautet wie:

for i:=1 to GridRowCount - 1
do if .... then
GridCound.Row[i].hide;
?

Das Feld 'comm' ist ja im DBGrid da und ich koennte mit der Field-
Eigenschaft drauf zugreifen und drei abzaehlen. Es scheitert jedoch
schon daran, dass ich nicht ahne, was "row" bei einem DBGrid sein
koennte.

Ob ich mit "hide" mir Dauerbalast in der Anwendung einhandle, der mir
in einigen Wochen eine Bremse ist, vermag ich nicht abzuschaetzen.


Nicole
Joe Galinke
2011-02-25 16:32:03 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Habe ich schon gestern. Und ausgedruckt. Und noch mal gelesen.
Wort fuer Wort von hinten nach vorne und von vorne nach hinten.
Ich habe alles so eingegeben, wie es drin stand.
Nope. Die Aliasangaben stimmten nicht.
Post by Nicole Wagner
Zu diesem Filter-Event finde ich rein gar nichts.
DataSet-Abkömmling aufs Formular, OI, Event OnFilterRecord markieren und F1
betätigen (Du verwendest D2010?).
Post by Nicole Wagner
Nicht in der Hilfe, nicht in meinen 100te-Seiten IB-Dokumentationen,
Nicht IB-Dokumentation, das ist ein Event des DataSets. Wenn Du Dir den
Rumpf des Eventhandlers per Doppelklick erstellen lässt sieht Du den
var-Parameter Accept. Über diesen regelst Du alles.

Die andere Filtermöglichkeit ist eine Eigenschaft. DataSet.Filter.
Post by Nicole Wagner
waere, dass ich genug verstehe, Datensatz-Zeilen zu loeschen.
Nicht löschen.
Post by Nicole Wagner
Ist das Filter-Event eigentlich der Weg des geringsten Widerstandes?
Im Grunde moechte ich die Zeilen nur nicht im Grid sehen, weil es
for i:=1 to GridRowCount - 1
do if .... then
GridCound.Row[i].hide;
Du hast das DbGrid noch immer nicht verstanden.

Das Grid stellt alle Zeilen Deiner Datenmenge dar, diese willst Du in ihrem
Umfang reduzieren. Sei das nun per Filter oder, meist besser, indem das
datenholende SQL-Statement die Daten entsprechend begrenzt.

Aber nun hast Du ja endlich eine Lösung.

Gruß, Joe
--
P.S.: Ja, ich kenne und verwende das cxGrid. Eigentlich nur.
Thomas G. Liesner
2011-02-21 21:45:05 UTC
Permalink
Post by Nicole Wagner
Select tbkontrakte.name_,
tbkontrakte.id_kontrakt as id
from tbkontrakte
where tbkontrakte.id_kontrakt in
(select first 3 tbkontrakte.id_kontrakt from tbkontrakte where
comm=tbkontrakte.comm order by name_ desc)
^^^^^^^^^^^^^^^^^^^^^

Du kannst auch gleich true hinschreiben, hat genauso wenig Sinn. Ohne
Alias kann Firebird nicht feststellen, dass du im Subquery auf Elemente
der Hauptquery zugreifen willst, sofern wie hier beide dieselbe Tabelle
abfragen.

So long,
Thomas G. Liesner
Nicole Wagner
2011-02-22 11:41:46 UTC
Permalink
Post by Thomas G. Liesner
Post by Nicole Wagner
Select tbkontrakte.name_,
tbkontrakte.id_kontrakt as id
from tbkontrakte
where tbkontrakte.id_kontrakt in
(select first 3 tbkontrakte.id_kontrakt from tbkontrakte where
comm=tbkontrakte.comm order by name_ desc)
^^^^^^^^^^^^^^^^^^^^^
Du kannst auch gleich true hinschreiben, hat genauso wenig Sinn. Ohne
Alias kann Firebird nicht feststellen, dass du im Subquery auf
Elemente der Hauptquery zugreifen willst, sofern wie hier beide
dieselbe Tabelle abfragen.
So long,
Thomas G. Liesner
hier noch ein Versuch, wie ich den Alias endlich DOCH aktivieren
konnte. Doch ich habe rein gar nichts davon:
Der Alias im Join wir syntaktisch nur dann akzeptiert, wenn ich in der
Select-Abfrage ebenfalls den Alias verwende. Will ich mit dem
Original-Tabellennamen darauf zugreifen, lese ich die Fehlermeldung wie
ganz unten:

select tbkurszeilen.fk_kontrakt as fkkontrakt,
tbkontrakt_.name_ as name_,
tbkontrakt_.comm as comm_
from tbkurszeilen
join
tbkontrakte as tbkontrakt_
on tbkurszeilen.fk_kontrakt = tbkontrakt_.id_kontrakt
/*$$IBEC$$ and tbkontrakte.name_='CLK5'

Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TBKONTRAKTE.NAME_.
At line 17, column 22. $$IBEC$$*/

Weisst Du einen Workaround?
Das darf doch nicht wahr sein, dass es nicht geht!


Nicole
Joe Galinke
2011-02-22 11:50:45 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Der Alias im Join wir syntaktisch nur dann akzeptiert, wenn ich in der
Select-Abfrage ebenfalls den Alias verwende. Will ich mit dem
Original-Tabellennamen darauf zugreifen, lese ich die Fehlermeldung wie
select tbkurszeilen.fk_kontrakt as fkkontrakt,
tbkontrakt_.name_ as name_,
tbkontrakt_.comm as comm_
from tbkurszeilen
join
tbkontrakte as tbkontrakt_
on tbkurszeilen.fk_kontrakt = tbkontrakt_.id_kontrakt
/*$$IBEC$$ and tbkontrakte.name_='CLK5'
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TBKONTRAKTE.NAME_.
At line 17, column 22. $$IBEC$$*/
Warum versuchst Du es nicht mit dem Alias anstatt des Tabellennamens?
Also
and tbkontrakt_.name_='CLK5'

Eine Zeile darüber hast Du es doch so gemacht.

Gruß, Joe
--
Nicole Wagner
2011-02-24 10:45:08 UTC
Permalink
... jetzt weiss ich nicht, ob dieses Posting raus ist.
Ich sehe eine Fehlermeldung dazu.
Sorry, falls doppelt.





Joe Galinke wrote:

...
Gru_, Joe
Hier bin ich wieder mit rauchendem Kopf.
Danke fuer die Muehe, die Du Dir gemacht hast!!
Und nicht nur Dank, sondern auch Glueckwunsch zu Deiner Faehigkeit
erfolgreich im Trueben zu Fischen. Denn das machst Du, wenn Du die
Tabellen nicht siehst.

Ich habe hier einmal etwas, das von der Syntax her akzeptiert wird.
Das ist die gute Nachricht.
Und noch eine gute: Es tut was.

die schlechte Nachricht:
Im Laufen hat es ein kleines und ein grosses Problem.

Das kleine Problem:
Es filtert nicht. Doch das liegt vermutlich daran, dass die
Einschraenkung wo anders hingehoert. Darueber kann ich nachdenken, wenn
das grosse Problem geloest ist.

Das grosse Problem ist diese, die letzte Zeile:
where tbkontrakte_sub.comm = tbkontrakte_.comm
auch akzeptiert als
where tbkontrakte_sub.comm = comm

Das hat Millionen von Zugriffen, die im ersten Select nicht sind.
Ich habe gegen 7000 tbkontrakte und gegen 1 Mio tbkurszeilen.
Das erste Select ist in Sekundenbruchteilen da.
Dann aber sehe ich einige Mio Zugriffe auf diese Zeile der
Subselect-Abfrage. Und das dauert gegen 15 Minuten.

Hast Du einen Rat?
Macht es Sinn, einen Index auf Comm zu legen?
Und ich denke fast, es wird hier ueber den Join zugegriffen und das
macht die Kaffeepause, nicht der nicht-Index.
Und ein Index fuer eine einzige Abfrage?
Denn sonstige Zugriffe auf COMM klappen recht flink.

Ganz wilde Idee:
Kann man allenfalls das Filter noch via Delphi in die Query
hineinschieben? Brauch die StringGrid die Query-Abfrage oder das
Query-Ergebnis?

Nicole


hier die Abfrage mit akzeptierter Syntax:

select tbkurszeilen_.fk_kontrakt as fk_kontrakt,
tbkontrakte_.name_ as name_,
tbkontrakte_.comm as comm,
tbkontrakte_.id_kontrakt as id_kontrakt,
tbkurszeilen_.fk_jdatum as datum,
tbkurszeilen_.o as o,
tbkurszeilen_.h as h,
tbkurszeilen_.l as l,
tbkurszeilen_.c as c,
tbkurszeilen_.volume as volume,
tbkurszeilen_.openinterest as openinterest,
tbkurszeilen_.long_stop as long_stop,
tbkurszeilen_.short_stop as short_stop,
tbkurszeilen_.fk_trade as fk_trade,
tbkurszeilen_.id_kurszeilen as id_kurszeilen,
tbkurszeilen_.baco as baco,
tbkurszeilen_.trflag as Tradeflag
from tbkurszeilen as tbkurszeilen_
join
tbkontrakte as tbkontrakte_
on tbkurszeilen_.fk_kontrakt = tbkontrakte_.id_kontrakt
and tbkurszeilen_.fk_jdatum = '15.9.2009'

where id_kontrakt in

(select first 3 tbkontrakte_.id_kontrakt
from tbkontrakte tbkontrakte_sub

left join tbkurszeilen as tbkurszeilen_sub2 on
(tbkurszeilen_sub2.fk_kontrakt = tbkontrakte_sub.id_kontrakt)

where tbkontrakte_sub.comm = tbkontrakte_.comm
);
Joe Galinke
2011-02-24 14:48:00 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
Es filtert nicht. Doch das liegt vermutlich daran, dass die
Einschraenkung wo anders hingehoert.
Würdest Du auch verraten _wonach_ gefiltert werden soll?
Post by Nicole Wagner
Das hat Millionen von Zugriffen, die im ersten Select nicht sind.
Ich habe gegen 7000 tbkontrakte und gegen 1 Mio tbkurszeilen.
Das erste Select ist in Sekundenbruchteilen da.
Dann aber sehe ich einige Mio Zugriffe auf diese Zeile der
Subselect-Abfrage. Und das dauert gegen 15 Minuten.
Hast Du einen Rat?
Macht es Sinn, einen Index auf Comm zu legen?
Warum probierst Du es nicht einfach aus? Das geht doch schnell.
ALTER TABLE .... (Index anlegen)
Post by Nicole Wagner
Und ich denke fast, es wird hier ueber den Join zugegriffen und das
macht die Kaffeepause, nicht der nicht-Index.
Und ein Index fuer eine einzige Abfrage?
Was stört daran?
Post by Nicole Wagner
Denn sonstige Zugriffe auf COMM klappen recht flink.
Kann man allenfalls das Filter noch via Delphi in die Query
hineinschieben?
Via Delphi in die Query hineinschieben? Was meinst Du damit?

Ob das DataSet selber filtern soll? Klar geht das, aber warum nicht gleich
im SELECT-Statement?

Es lokal, also im Code zu filtern bedeutet natürlich auch, dass die
Datensätze erstmal gelesen werden. Je nach Anbindung zur Datenbank kann das
schon störend bremsen. Aber auch wenn das konkret nicht der Fall ist es
einfach sauberer und passend bei der Abfrage selbst getan.
Post by Nicole Wagner
Brauch die StringGrid die Query-Abfrage oder das
Query-Ergebnis?
Diese Frage dürfte eigentlich schon nicht mehr kommen.
Das Grid ist über die DataSource mit der Daten_menge_ (Dataset) verbunden.
Es kennt kein SQL und interessiert sich nicht dafür.

Ja, wenn Du nun die Filtereigenschaft des Datasets verwendest, dann wirkt
sich das auch direkt auf die Darstellung im Grid aus.


Gruß, Joe
--
Joe Galinke
2011-02-24 15:00:04 UTC
Permalink
Hallo Joe,
Post by Joe Galinke
Würdest Du auch verraten _wonach_ gefiltert werden soll?
Ich hatte es so verstanden, als handele es sich um ein weiteres, neues
Kriterium. Aber das war wohl Unsinn.

Warum verwendest Du nicht konsequent den Alias?
Post by Joe Galinke
where tbkontrakte_.id_kontrakt in
^^^^^^^^^^^^ /* Der Alias der Hauptabfrage. Deshalb schrieb
ich immer _MAIN*/
Post by Joe Galinke
(select first 3 tbkontrakte_SUB.id_kontrakt
^^^ /*das dürfte entscheidend sein */
Post by Joe Galinke
from tbkontrakte tbkontrakte_sub
left join tbkurszeilen as tbkurszeilen_sub2 on
(tbkurszeilen_sub2.fk_kontrakt = tbkontrakte_sub.id_kontrakt)
where tbkontrakte_sub.comm = tbkontrakte_.comm
);
Gruß, Joe
--
Nicole Wagner
2011-02-24 16:48:37 UTC
Permalink
Post by Joe Galinke
Hallo Joe,
Würdest Du auch verraten wonach gefiltert werden soll?
Ich hatte es so verstanden, als handele es sich um ein weiteres, neues
Kriterium. Aber das war wohl Unsinn.
Warum verwendest Du nicht konsequent den Alias?
weil es nicht akzeptiert wird von der Syntax.

Du glaubst nicht, wieviele Stunden ich gesessen bin, nur um die Syntax
hinzubekommen. Und eine Stunde ist schnell beisammen, wenn eine Abfrage
zuweilen 15 Minuten dauert. Anfangs wusste ich ja nicht, welches
Schnipsel genau mir die Wartezeit verursachte. Da sass ich wieder vor
der Sanduhr und wollte.... ach was,.... einfach nur weitermachen.


Nicole
Joe Galinke
2011-02-24 17:05:20 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
weil es nicht akzeptiert wird von der Syntax.
Hast Du meine Änderungsvorschläge ausprobiert? Mache es bitte und kopiere
das Statement _danach_bitte_ in die nächste Antwort.



Gruß, Joe
--
Matthias Frey
2011-02-25 09:38:40 UTC
Permalink
Post by Nicole Wagner
Post by Joe Galinke
Warum verwendest Du nicht konsequent den Alias?
weil es nicht akzeptiert wird von der Syntax.
Du glaubst nicht, wieviele Stunden ich gesessen bin, nur um die Syntax
hinzubekommen. Und eine Stunde ist schnell beisammen, wenn eine Abfrage
zuweilen 15 Minuten dauert.
Versteh ich nicht. Wenn die Syntax nicht stimmt, dann komt die
Fehlermeldung doch sofort und nicht erst nach 15 Minuten.
Post by Nicole Wagner
Nicole
Matthias
Nicole Wagner
2011-02-24 16:45:08 UTC
Permalink
Post by Joe Galinke
Post by Nicole Wagner
Hast Du einen Rat?
Macht es Sinn, einen Index auf Comm zu legen?
Warum probierst Du es nicht einfach aus? Das geht doch schnell.
ALTER TABLE .... (Index anlegen)
.... weil das > 1 Mio Eintraege sind.
Mein Lehrbuch behauptet, auch zuviele Indizes machen langsam.
Post by Joe Galinke
Diese Frage dürfte eigentlich schon nicht mehr kommen.
Das Grid ist über die DataSource mit der Daten_menge_ (Dataset)
verbunden. Es kennt kein SQL und interessiert sich nicht dafür.
Ja, wenn Du nun die Filtereigenschaft des Datasets verwendest, dann
wirkt sich das auch direkt auf die Darstellung im Grid aus.
Ich weiss zwar noch nicht, was die Filtereigenschaft des Datasets ist,
doch ich werde mal probieren, ob ich es zusammenbringe.

Ich werde dafuer ein Event suchen, denke ich?
Halte mir die Dauemn, dass ich es finde.



Nicole
Joe Galinke
2011-02-24 17:17:35 UTC
Permalink
Hallo Nicole,
Post by Nicole Wagner
.... weil das > 1 Mio Eintraege sind.
Mein Lehrbuch behauptet, auch zuviele Indizes machen langsam.
_Was_ machen sie langsam?
Die Abfrage? Eher nicht.
Einfügen und löschen von Datensätzen? Ja. Aber spielt es eine Rolle? Evtl.,
wenn man _oft_viele_ Datensätze einträgt oder löscht.

Aber unabhängig davon, das ist alles kein Grund es nicht mal schnell
auszuprobieren.
Post by Nicole Wagner
Ich werde dafuer ein Event suchen, denke ich?
Es gibt das Event OnFilterRecord. Dort kannst Du jeden Datensatz schön
umständlich per Code prüfen ob er dazugehört oder nicht.

Dann gibt es noch die Eigenschaft Filter: string.
DataSet.Filter := 'MyIntColumn=1 or MyVarChar=''Hello World''':

In beiden Fällen muss Dataset.Filtered auf True gesetzt werden, damit auch
gefiltert wird.
Post by Nicole Wagner
Halte mir die Dauemn, dass ich es finde.
Nein, ich halte Dir die Daumen, dass Du zur Vernunft kommst. Sorry.
Das gilt für den Fall, dass Du damit das "in dem anderen Posting"
beschriebene Problem lösen willst.


Gruß, Joe
--
Joe Galinke
2011-02-24 17:28:50 UTC
Permalink
Hallo Joe,
Post by Joe Galinke
Nein, ich halte Dir die Daumen, dass Du zur Vernunft kommst.
und vergaß:

:-)


Gruß, Joe
--
Thomas G. Liesner
2011-02-24 17:05:38 UTC
Permalink
Post by Nicole Wagner
.... weil das > 1 Mio Eintraege sind.
Mein Lehrbuch behauptet, auch zuviele Indizes machen langsam.
Jeder Index verlängert den Zeitaufwand beim Einfügen neuer Einträge bzw.
beim Ändern von Spalten, die Teil eines Index sind. Bei Abfragen sind
Indizes entweder neutral (weil sie für die konkrete Abfrage nicht
verwendbar sind) oder beschleunigen die Sache ggf. sogar um
Größenordnungen. Wenn du also nicht andauernd Tausende von Datensätzen
in einem sehr, sehr engen Zeitintervall einfügen musst, sondern mehr mit
Auswertungen beschäftigt bist, ist dieser Ratschlag also reiner Quatsch.
Post by Nicole Wagner
Post by Joe Galinke
Ja, wenn Du nun die Filtereigenschaft des Datasets verwendest, dann
wirkt sich das auch direkt auf die Darstellung im Grid aus.
Ich weiss zwar noch nicht, was die Filtereigenschaft des Datasets ist,
doch ich werde mal probieren, ob ich es zusammenbringe.
Das würde ich eher steckenlassen. Es filtert, was die SQL-Abfrage übrig
lässt, filterst du also hauptsächlich dort, werden trotzdem massenweise
Daten vom Server an den Client übertragen.

BTW: Mach doch einfach eine Spieldatenbank mit 40 Datensätzen und
gleicher Struktur auf und teste deine Statements dort gründlich aus,
bevor du es auf eine Datenmenge losläßt, die derartige Wartezeiten mit
sich bringt.

So long,
Thomas G. Liesner
Thomas G. Liesner
2011-02-22 14:53:09 UTC
Permalink
Post by Nicole Wagner
Der Alias im Join wir syntaktisch nur dann akzeptiert, wenn ich in der
Select-Abfrage ebenfalls den Alias verwende.
Und was ist das Problem dabei?

So long,
Thomas G. Liesner
Michael Dombrowski
2011-02-25 12:41:43 UTC
Permalink
Post by Nicole Wagner
Hier noch mal meine Query auf das Notwendige reduziert.
Primaerschluessel hatte ich keinen abgefragt. Brauche ich denn den
unbedingt?
select tbkurszeilen.fk_kontrakt as fk_kontrakt,
/* der Primäschlüssel lautete: id_kurszeilen, */
tbkontrakte.comm as comm,
tbkurszeilen.fk_jdatum as datum,
tbkurszeilen.openinterest as openinterest,
from tbkurszeilen /* hier kann ich kein Alias einfügen ! */
join
tbkontrakte on tbkurszeilen.fk_kontrakt = tbkontrakte.id_kontrakt
and tbkurszeilen.fk_jdatum = '15.9.2009' ;
von dieser Abfrage will ich die ERSTEN drei Werte JEWEILS zu den
verschiedenen Comm-Treffern haben. Hierbei brauche ich also open
interest von der ersten Tabelle (JE drei Treffer) und Comm (zu ALLEN
Comm) von der join-Tabelle.
@Joe: wie ich das mit First und Skip loesen kann, weiss ich nicht. Denn
ich will ja nicht die ersten 3 Treffer insgesamt haben, sondern JEWEILS
zu JEDER Comm. Alle meine Versuche mit First haben leider nur INSGESAMT
drei Datensaetze ausgegeben.
Hallo Nicole,

FIRST und SKIP sind für Dein Problem auch der falsche Ansatz. So geht es
besser:

-- Start SQL ----------------------------------------------------------
WITH
/* Maximalwert von OPENINTEREST gruppiert nach FK_KONTRAKT und
FK_JDATUM */
max1 AS ( SELECT FK_KONTRAKT AS FK_KONTRAKT1,
FK_JDATUM AS FK_JDATUM1,
MAX(OPENINTEREST) AS OPENINTEREST1
FROM TBKURSZEILEN
WHERE FK_JDATUM = '15.9.2009'
GROUP BY FK_KONTRAKT, FK_JDATUM),
/* zweitgrößter Wert von OPENINTEREST gruppiert nach FK_KONTRAKT
und FK_JDATUM */
max2 AS ( SELECT FK_KONTRAKT AS FK_KONTRAKT2,
FK_JDATUM AS FK_JDATUM2,
MAX(OPENINTEREST) AS OPENINTEREST2
FROM TBKURSZEILEN
JOIN max1 ON FK_KONTRAKT = FK_KONTRAKT1
WHERE FK_JDATUM = '15.9.2009'
AND OPENINTEREST < OPENINTEREST1 /* größter Wert, der
kleiner als der Maximalwert ist */
GROUP BY FK_KONTRAKT, FK_JDATUM),
/* drittgrößter Wert von OPENINTEREST gruppiert nach FK_KONTRAKT
und FK_JDATUM */
max3 AS ( SELECT FK_KONTRAKT AS FK_KONTRAKT3,
FK_JDATUM AS FK_JDATUM3,
MAX(OPENINTEREST) AS OPENINTEREST3
FROM TBKURSZEILEN
JOIN max2 ON FK_KONTRAKT = FK_KONTRAKT2
WHERE FK_JDATUM = '15.9.2009'
AND OPENINTEREST < OPENINTEREST2 /* größter Wert, der
kleiner als der zweitgrößte Wert ist */
GROUP BY FK_KONTRAKT, FK_JDATUM)
/* alle Kontrakte zum Maximalwert */
SELECT COMM,
FK_JDATUM1 AS FK_JDATUM,
OPENINTEREST1 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max1 ON FK_KONTRAKT1 = ID_KONTRAKT
UNION ALL
/* alle Kontrakte zum zweitgrößten Wert */
SELECT COMM,
FK_JDATUM2 AS FK_JDATUM,
OPENINTEREST2 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max2 ON FK_KONTRAKT2 = ID_KONTRAKT
UNION ALL
/* alle Kontrakte zum drittgrößten Wert */
SELECT COMM,
FK_JDATUM3 AS FK_JDATUM,
OPENINTEREST3 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max3 ON FK_KONTRAKT3 = ID_KONTRAKT
ORDER BY 1, 3 DESC
-- Ende SQL -----------------------------------------------------------

Zuerst sammelst Du über max1 bis max3 die drei größten Werte zu jedem
Kontrakt separat ein. (Wenn Du hier einen Datumsbereich auswählen
solltest, mußt Du das Datum aus den Feldlisten des SELECT und GROUP BY
entfernen.) Dann ließt Du dazu auch alle Kontrakte separat und machst
mit dem UNION eine gemeinsame Datenmenge daraus.

Ein mögliches Problem ist, wenn der Maximalwert und/oder zweitgrößte
Wert je Kontrakt mehr als einmal vorkommen. Dann wird trotzdem der
nächstkleinere selektiert.

Ein Index auf FK_JDATUM sollte in diesem Fall auch vorhanden sein.

Gruß,
Michael
Nicole Wagner
2011-02-25 15:36:02 UTC
Permalink
Post by Michael Dombrowski
-- Start SQL
---------------------------------------------------------- WITH
/* Maximalwert von OPENINTEREST gruppiert nach FK_KONTRAKT und
FK_JDATUM */ max1 AS ( SELECT FK_KONTRAKT AS FK_KONTRAKT1,
FK_JDATUM AS FK_JDATUM1,
MAX(OPENINTEREST) AS OPENINTEREST1
FROM TBKURSZEILEN
WHERE FK_JDATUM = '15.9.2009'
GROUP BY FK_KONTRAKT, FK_JDATUM),
/* zweitgrößter Wert von OPENINTEREST gruppiert nach FK_KONTRAKT
und FK_JDATUM */ max2 AS ( SELECT FK_KONTRAKT AS
FK_KONTRAKT2, FK_JDATUM AS FK_JDATUM2,
MAX(OPENINTEREST) AS OPENINTEREST2
FROM TBKURSZEILEN
JOIN max1 ON FK_KONTRAKT = FK_KONTRAKT1
WHERE FK_JDATUM = '15.9.2009'
AND OPENINTEREST < OPENINTEREST1 /* größter Wert,
der kleiner als der Maximalwert ist */ GROUP BY
FK_KONTRAKT, FK_JDATUM), /* drittgrößter Wert von OPENINTEREST
gruppiert nach FK_KONTRAKT und FK_JDATUM */ max3 AS ( SELECT
FK_KONTRAKT AS FK_KONTRAKT3, FK_JDATUM
AS FK_JDATUM3, MAX(OPENINTEREST) AS
OPENINTEREST3 FROM TBKURSZEILEN
JOIN max2 ON FK_KONTRAKT = FK_KONTRAKT2
WHERE FK_JDATUM = '15.9.2009'
AND OPENINTEREST < OPENINTEREST2 /* größter Wert,
der kleiner als der zweitgrößte Wert ist */ GROUP BY
FK_KONTRAKT, FK_JDATUM) /* alle Kontrakte zum Maximalwert */
SELECT COMM,
FK_JDATUM1 AS FK_JDATUM,
OPENINTEREST1 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max1 ON FK_KONTRAKT1 = ID_KONTRAKT
UNION ALL
/* alle Kontrakte zum zweitgrößten Wert */
SELECT COMM,
FK_JDATUM2 AS FK_JDATUM,
OPENINTEREST2 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max2 ON FK_KONTRAKT2 = ID_KONTRAKT
UNION ALL
/* alle Kontrakte zum drittgrößten Wert */
SELECT COMM,
FK_JDATUM3 AS FK_JDATUM,
OPENINTEREST3 AS OPENINTEREST
FROM TBKONTRAKTE
JOIN max3 ON FK_KONTRAKT3 = ID_KONTRAKT
ORDER BY 1, 3 DESC
-- Ende SQL
-----------------------------------------------------------
--
Lieber Michael,


ein grosses Danke auch Dir fuer die Arbeit, die Du Dir gemacht hast!

Das Statement hat sofort funktioniert. Nicht ein Tippfehler oder
Beistrich zu aendern. Ich lese es ganz begeistert, weil da einiges
drinnen ist, das ich noch nie gehoert habe. Und jetzt habe ich ein
Beispiel dazu mit meinem Tabellen.


Test erster Aufruf:
Es arbeitet mittelschnell.
Die Analyse sagt viele Zugriffe auf tbkurszeilen.

Die Ausgabe sieht leider so aus wie unten:
Es werden mehr als 3 COMM ausgeben.
AD ist nur zufaellig richtig, weil ich nur 3 habe.

verhext!


Nicole


COMM FK_JDATUM OPENINTEREST
AD 15.09.2009 104.735
AD 15.09.2009 29
AD 15.09.2009 15
BO 15.09.2009 123.843
BO 15.09.2009 27.307
BO 15.09.2009 24.998
BO 15.09.2009 15.529
BO 15.09.2009 10.108
BO 15.09.2009 8.831
BO 15.09.2009 8.073
BO 15.09.2009 841
BO 15.09.2009 446
BO 15.09.2009 430
BO 15.09.2009 2
BP 15.09.2009 67.036
BP 15.09.2009 98
BP 15.09.2009 20
BP 15.09.2009 2
C 15.09.2009 530.169
C 15.09.2009 139.975
C 15.09.2009 68.178
C 15.09.2009 65.651
C 15.09.2009 32.583
C 15.09.2009 12.388
C 15.09.2009 5.569
C 15.09.2009 1.979
C 15.09.2009 1.452
C 15.09.2009 745
C 15.09.2009 221
C 15.09.2009 162
C 15.09.2009 20
CC 15.09.2009 62.979
CC 15.09.2009 35.591
CC 15.09.2009 9.018
CC 15.09.2009 4.256
CC 15.09.2009 3.809
CC 15.09.2009 3.367
CC 15.09.2009 1.983
CC 15.09.2009 1.981
CD 15.09.2009 87.519
CD 15.09.2009 1.179
CD 15.09.2009 360
CD 15.09.2009 260
CD 15.09.2009 15
CL 15.09.2009 274.811
CL 15.09.2009 170.254
CL 15.09.2009 111.923
CL 15.09.2009 104.810
CL 15.09.2009 79.862
CL 15.09.2009 57.366
CL 15.09.2009 31.746
CL 15.09.2009 29.188
CL 15.09.2009 28.358
CL 15.09.2009 18.448
CL 15.09.2009 14.965
CL 15.09.2009 14.480
CL 15.09.2009 13.206
CL 15.09.2009 11.217
CL 15.09.2009 9.908
1
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
CL 15.09.2009 243
CR 15.09.2009 800
CR 15.09.2009 423
CT 15.09.2009 96.629
CT 15.09.2009 26.240
CT 15.09.2009 3.984
CT 15.09.2009 3.511
CT 15.09.2009 3.242
CT 15.09.2009 770
CT 15.09.2009 61
CT 15.09.2009 33
CT 15.09.2009 4
CU 15.09.2009 155.919
CU 15.09.2009 550
CU 15.09.2009 52
CU 15.09.2009 1
ED 15.09.2009 6.384.711
ED 15.09.2009 6.384.711
ED 15.09.2009 6.384.711
ED 15.09.2009 991.182
ED 15.09.2009 974.284
ED 15.09.2009 856.519
ED 15.09.2009 752.621
ED 15.09.2009 667.766
ED 15.09.2009 3.944
ED 15.09.2009 1.670
ED 15.09.2009 628
ED 15.09.2009 523
ED 15.09.2009 433
ED 15.09.2009 295
ED 15.09.2009 156
ES 15.09.2009 2.093.060
ES 15.09.2009 991.882
ES 15.09.2009 209
ES 15.09.2009 9
ES 15.09.2009 0
GC 15.09.2009 474.408
GC 15.09.2009 474.408
GC 15.09.2009 342.494
GC 15.09.2009 21.877
GC 15.09.2009 21.572
GC 15.09.2009 20.453
GC 15.09.2009 12.418
GC 15.09.2009 12.060
GC 15.09.2009 7.733
GC 15.09.2009 3.769
GC 15.09.2009 812
GC 15.09.2009 779
GC 15.09.2009 447
GC 15.09.2009 121
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 89.155
HG 15.09.2009 12.631
HG 15.09.2009 2.425
HG 15.09.2009 2.289
2
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
HG 15.09.2009 2.123
HG 15.09.2009 1.497
HG 15.09.2009 1.477
HG 15.09.2009 752
HG 15.09.2009 195
HG 15.09.2009 42
HG 15.09.2009 6
HO 15.09.2009 57.768
HO 15.09.2009 53.994
HO 15.09.2009 41.245
HO 15.09.2009 30.452
HO 15.09.2009 21.871
HO 15.09.2009 16.860
HO 15.09.2009 15.842
HO 15.09.2009 15.595
HO 15.09.2009 11.988
HO 15.09.2009 11.342
HO 15.09.2009 6.605
HO 15.09.2009 5.803
HO 15.09.2009 4.723
HO 15.09.2009 4.349
HO 15.09.2009 4.079
HO 15.09.2009 3.092
HO 15.09.2009 2.660
HO 15.09.2009 2.184
HO 15.09.2009 1.446
HO 15.09.2009 1.268
HO 15.09.2009 1.016
HO 15.09.2009 730
HO 15.09.2009 708
HO 15.09.2009 308
HO 15.09.2009 300
HO 15.09.2009 259
HO 15.09.2009 200
HO 15.09.2009 139
HO 15.09.2009 90
HO 15.09.2009 62
HO 15.09.2009 39
HO 15.09.2009 3
HO 15.09.2009 2
JY 15.09.2009 108.363
JY 15.09.2009 73
JY 15.09.2009 1
JY 15.09.2009 1
KC 15.09.2009 64.633
KC 15.09.2009 16.397
KC 15.09.2009 8.373
KC 15.09.2009 2.591
KC 15.09.2009 2.315
KC 15.09.2009 1.627
KC 15.09.2009 206
KC 15.09.2009 54
KC 15.09.2009 31
KC 15.09.2009 26
KC 15.09.2009 4
NG 15.09.2009 147.133
NG 15.09.2009 122.410
NG 15.09.2009 72.545
NG 15.09.2009 67.991
3
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
NG 15.09.2009 43.383
NG 15.09.2009 38.974
NG 15.09.2009 24.749
NG 15.09.2009 24.642
NG 15.09.2009 21.100
NG 15.09.2009 13.538
NG 15.09.2009 11.100
NG 15.09.2009 10.440
NG 15.09.2009 8.888
NG 15.09.2009 8.539
NG 15.09.2009 6.392
NG 15.09.2009 1.990
NG 15.09.2009 1.562
NG 15.09.2009 679
NG 15.09.2009 394
NG 15.09.2009 336
NG 15.09.2009 180
NG 15.09.2009 167
NG 15.09.2009 131
NG 15.09.2009 122
NG 15.09.2009 116
NG 15.09.2009 109
NG 15.09.2009 99
NG 15.09.2009 97
NG 15.09.2009 96
NG 15.09.2009 95
NG 15.09.2009 91
NG 15.09.2009 89
NG 15.09.2009 88
NG 15.09.2009 68
NG 15.09.2009 31
NG 15.09.2009 22
NG 15.09.2009 19
NG 15.09.2009 18
NG 15.09.2009 17
NG 15.09.2009 13
NG 15.09.2009 6
NG 15.09.2009 6
NG 15.09.2009 4
NG 15.09.2009 2
NG 15.09.2009 2
NG 15.09.2009 1
NQ 15.09.2009 240.087
NQ 15.09.2009 173.035
NQ 15.09.2009 12
O 15.09.2009 11.961
O 15.09.2009 2.134
O 15.09.2009 8
O 15.09.2009 4
OJ 15.09.2009 23.128
OJ 15.09.2009 2.889
OJ 15.09.2009 2.193
OJ 15.09.2009 443
OJ 15.09.2009 180
OJ 15.09.2009 85
OJ 15.09.2009 1
PL 15.09.2009 21.016
PL 15.09.2009 7.915
PL 15.09.2009 120
4
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
RB 15.09.2009 62.268
RB 15.09.2009 50.402
RB 15.09.2009 31.072
RB 15.09.2009 18.893
RB 15.09.2009 9.597
RB 15.09.2009 6.365
RB 15.09.2009 6.238
RB 15.09.2009 5.155
RB 15.09.2009 3.895
RB 15.09.2009 2.838
RB 15.09.2009 1.438
RB 15.09.2009 1.308
RB 15.09.2009 1.202
RB 15.09.2009 918
RB 15.09.2009 686
RB 15.09.2009 36
S 15.09.2009 254.267
S 15.09.2009 66.037
S 15.09.2009 32.070
S 15.09.2009 28.099
S 15.09.2009 24.967
S 15.09.2009 23.363
S 15.09.2009 922
S 15.09.2009 338
S 15.09.2009 258
S 15.09.2009 201
S 15.09.2009 111
S 15.09.2009 40
S 15.09.2009 15
SB 15.09.2009 315.521
SB 15.09.2009 155.121
SB 15.09.2009 113.510
SB 15.09.2009 74.022
SB 15.09.2009 68.394
SB 15.09.2009 44.505
SB 15.09.2009 14.189
SB 15.09.2009 13.215
SB 15.09.2009 11.540
SB 15.09.2009 8.880
SB 15.09.2009 3.169
SB 15.09.2009 2.506
SF 15.09.2009 44.927
SF 15.09.2009 80
SI 15.09.2009 94.750
SI 15.09.2009 10.337
SI 15.09.2009 3.734
SI 15.09.2009 2.900
SI 15.09.2009 2.808
SI 15.09.2009 2.314
SI 15.09.2009 339
SI 15.09.2009 141
SI 15.09.2009 3
SM 15.09.2009 77.583
SM 15.09.2009 28.217
SM 15.09.2009 13.060
SM 15.09.2009 12.376
SM 15.09.2009 11.509
SM 15.09.2009 7.696
SM 15.09.2009 4.967
5
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
SM 15.09.2009 2.113
SM 15.09.2009 1.984
SM 15.09.2009 1.133
SM 15.09.2009 93
SM 15.09.2009 52
SM 15.09.2009 35
SM 15.09.2009 11
SP 15.09.2009 321.652
SP 15.09.2009 144.251
SP 15.09.2009 4.271
SP 15.09.2009 181
SP 15.09.2009 0
TY 15.09.2009 1.060.718
TY 15.09.2009 33.871
US 15.09.2009 729.357
US 15.09.2009 15.068
US 15.09.2009 158
W 15.09.2009 203.716
W 15.09.2009 44.912
W 15.09.2009 44.653
W 15.09.2009 16.336
W 15.09.2009 7.632
W 15.09.2009 893
W 15.09.2009 727
W 15.09.2009 52
W 15.09.2009 41
W 15.09.2009 16
6
25.02.2011 16:18:10
Michael Dombrowski
2011-02-25 16:14:57 UTC
Permalink
Post by Nicole Wagner
Es arbeitet mittelschnell.
Die Analyse sagt viele Zugriffe auf tbkurszeilen.
Hallo Nicole,

da fehlt dann wahrscheinlich ein Index auf FK_JDATUM.
Post by Nicole Wagner
Es werden mehr als 3 COMM ausgeben.
AD ist nur zufaellig richtig, weil ich nur 3 habe.
[...]
Post by Nicole Wagner
COMM FK_JDATUM OPENINTEREST
AD 15.09.2009 104.735
AD 15.09.2009 29
AD 15.09.2009 15
BO 15.09.2009 123.843
BO 15.09.2009 27.307
BO 15.09.2009 24.998
BO 15.09.2009 15.529
BO 15.09.2009 10.108
BO 15.09.2009 8.831
BO 15.09.2009 8.073
BO 15.09.2009 841
BO 15.09.2009 446
BO 15.09.2009 430
BO 15.09.2009 2
Kann es sein, daß es verschiedenen COMM's (z.B. BO) mehrmals in der
Tabelle TBKONTRAKTE vorkommen? Dann wird das so natürlich nichts. Dazu
wäre die Ausgabe diese SQL_Statements interessant:

SELECT COUNT(COMM) AS COM_CNT,
COMM
FROM TBKONTRAKTE
GROUP BY COMM
HAVING COUNT(COMM) > 1
ORDER BY COMM

Das ließt Dir alle COMM's aus, die mehr als einmal vorkommen. Wenn da
Datensätze zurückkommen, Packst Du in max1 bis max3 aus meinem Beispiel
je einen JOIN auf die Tabelle TBKONTRAKTE über FK_KONTRAKT=ID_KONTRAKT
und ersetzt FK_KONTRAKT in den SELECT und GROUP BY Feldlisten durch
COMM. In den drei UNION-Abschnitten selektierst Du dann nur noch max1
bis max3 ohne JOIN.

Gruß,
Michael
Nicole Wagner
2011-02-25 17:42:33 UTC
Permalink
Post by Joe Galinke
Post by Nicole Wagner
Es arbeitet mittelschnell.
Die Analyse sagt viele Zugriffe auf tbkurszeilen.
Hallo Nicole,
da fehlt dann wahrscheinlich ein Index auf FK_JDATUM.
Post by Nicole Wagner
Es werden mehr als 3 COMM ausgeben.
AD ist nur zufaellig richtig, weil ich nur 3 habe.
[...]
Post by Nicole Wagner
COMM FK_JDATUM OPENINTEREST
AD 15.09.2009 104.735
AD 15.09.2009 29
AD 15.09.2009 15
BO 15.09.2009 123.843
BO 15.09.2009 27.307
BO 15.09.2009 24.998
BO 15.09.2009 15.529
BO 15.09.2009 10.108
BO 15.09.2009 8.831
BO 15.09.2009 8.073
BO 15.09.2009 841
BO 15.09.2009 446
BO 15.09.2009 430
BO 15.09.2009 2
Kann es sein, daß es verschiedenen COMM's (z.B. BO) mehrmals in der
Tabelle TBKONTRAKTE vorkommen? Dann wird das so natürlich nichts.
SELECT COUNT(COMM) AS COM_CNT,
COMM
FROM TBKONTRAKTE
GROUP BY COMM
HAVING COUNT(COMM) > 1
ORDER BY COMM
Das ließt Dir alle COMM's aus, die mehr als einmal vorkommen. Wenn da
Datensätze zurückkommen, Packst Du in max1 bis max3 aus meinem
Beispiel je einen JOIN auf die Tabelle TBKONTRAKTE über
FK_KONTRAKT=ID_KONTRAKT und ersetzt FK_KONTRAKT in den SELECT und
GROUP BY Feldlisten durch COMM. In den drei UNION-Abschnitten
selektierst Du dann nur noch max1 bis max3 ohne JOIN.
Gruß,
Michael
Klar kommen die mehr als einmal vor. Und man weiss nicht, wie oft.
Es handelt sich um Daten zu Rohstoffpreisen
(Rohstoff = commodity = COMM).

Der Aufbau ist dieser:
Jeden Tag gibt es bestimmte Werte inklusive dem Wert "open interest".
Also z.B.
15.9.2009 .....oi=104735; Schlusskurs = 100
16.9.2009 ..... 124735...
17.9.2009 ..... 14735----

WOHIN gehoert jetzt dieser Satz mit taeglichen Daten:
Dazu gibt es einen FK in jeder Tagezeile.
Dieser FK zeigt auf die Eckdaten der jeweiligen Kursreihe, wie
Rohstoff, Liefermonat, uam.

Meine Abfrage soll das tun:
Sie soll mir die 3 liquidesten Kontrakte zu einem bestimmten Datum
anzeigen. Also z.B.

BO 15.09.2009 123.843
BO 15.09.2009 27.307
BO 15.09.2009 24.998

BO steht fuer Sojabohnen-Oel. Innerhalb des FK-Zeigers gibt es noch den
Liefermonat, der in der Abfrage zur Zeit kein Feld hat. Gefuehsmaessig
wuerde ich jetzt sagen, es konnte sich um Dezember 2009, Jaenner und
Maerz 2010 handeln. Das heisst, wir sprechen z.B. von Sojabohnenoel,
das im Maerz 2010 zu liefern ist.

Die Abfrage sagt Dir also, dass am 15.9.2009 die Uebernacht-Positionen
fuer die Dezember Faelligkeit rund 124.000 Kontrakte waren. Und im Jahr
drauf noch immer ueber 20.000. Daher weisst Du, dass Du zwar am besten
BO im Dezember handelst, aber Dich auch vor dem naechsten Jahr nicht
fuerchten musst.

Liest Du hingegen AD => 15. Dann werden genau 15 (Einheiten)
Australische Dollar gehalten. Lieferfrist muss Maerz oder Juni 2010
sein. Da solltest Du Dich heftig fuerchten, dass sie Dich nicht an die
Wand stellen und Dir den Preis diktieren. Denn in dem Markt bist Du
alleine mit vermutlich nur einem einzigen Hai, der alle 15 Einheiten
hat. Was wird der wohl mit der kleinen Nicole machen, wenn sie aus dem
Becken/Markt wieder raus will? ;-(
Besser sie lernt SQL und geht dort nicht rein.

Mehr als drei Rohstoffkontrakte brauche ich nicht zu einem Datum. Denn
vor allem, was das viertschlechteste ist, muss man sich sowieso
fuerchten, huuu :-()

;-)


==================================

Gibt es vielleicht noch einen anderen Weg des Filterns?

Es wird mit diesen SQL-Konstrukten so langsam. Ich habe ohne Filter ein
adrettes Datenset mit vielleicht 100 Saetzen, die in
Sekundenbruchteilen da sind.

Davon muss man rund 40-50 abschiessen.
Das muss schneller gehen als in 2 Minuten oder gar 15.
So vom Hausverstand muesste es gehen. Ohne zusetzlichen Index. Ich
weiss nur leider nicht wie.


Nicole
Michael Dombrowski
2011-02-25 19:20:06 UTC
Permalink
Post by Nicole Wagner
Post by Michael Dombrowski
Kann es sein, daß es verschiedenen COMM's (z.B. BO) mehrmals in der
Tabelle TBKONTRAKTE vorkommen?
[...]
Post by Nicole Wagner
Post by Michael Dombrowski
Das ließt Dir alle COMM's aus, die mehr als einmal vorkommen. Wenn da
Datensätze zurückkommen, Packst Du in max1 bis max3 aus meinem
Beispiel je einen JOIN auf die Tabelle TBKONTRAKTE über
FK_KONTRAKT=ID_KONTRAKT und ersetzt FK_KONTRAKT in den SELECT und
GROUP BY Feldlisten durch COMM. In den drei UNION-Abschnitten
selektierst Du dann nur noch max1 bis max3 ohne JOIN.
Klar kommen die mehr als einmal vor. Und man weiss nicht, wie oft.
Dann ändere das Beispiel so wie ich geschrieben habe.
Post by Nicole Wagner
Gibt es vielleicht noch einen anderen Weg des Filterns?
Es wird mit diesen SQL-Konstrukten so langsam. Ich habe ohne Filter ein
adrettes Datenset mit vielleicht 100 Saetzen, die in
Sekundenbruchteilen da sind.
Steht genau diese Abfrage irgendwo im Thread? Die könnte man als
Unterabfrage in max1-3 verwenden.

Wie auch schon von anderen geschrieben: ohne Index wird es nicht
schneller. Mach eine Kopie von deiner DB (falls Du sie nicht sowieso
schon hast) und lege einen Index auf FK_JDATUM an. Dann teste nochmal.

Noch ein Link zu Firebird und Indices:
<http://paulbeachsblog.blogspot.com/2011/01/quick-start-guide-to-index-optimisation.html>
Post by Nicole Wagner
Davon muss man rund 40-50 abschiessen.
Das muss schneller gehen als in 2 Minuten oder gar 15.
So vom Hausverstand muesste es gehen. Ohne zusetzlichen Index. Ich
weiss nur leider nicht wie.
Wenn ich mich recht erinnere, hast Du in diesem Thread erwähnt, das ca.
1Mio. Datensätze im Spiel sind. Eine Abfrage, die keinen Index im WHERE
oder JOIN verwenden kann, muß sich dann _jeden_ Datensatz der Tabelle
ansehen. Mit Index nur einen Bruchteil. IBExpert hat da eine schöne
Grafik nach einer Abfrage. Vergleich einfach mal die Anzahl der
abgefragten Datensätze mit und ohne Index.

Auch in den Plan Analyzer solltest Du beim Testen eines Statements immer
schauen. Alle Stellen, an denen NATURAL steht, sind verdächtig.


Gruß,
Michael
Nicole Wagner
2011-02-25 16:11:19 UTC
Permalink
Sende Posting noch einmal, weil es moeglicherweise als Signatur
verarbeitet worden ist.


Lieber Michael,


ein grosses Danke auch Dir fuer die Arbeit, die Du Dir gemacht hast!

Das Statement hat sofort funktioniert. Nicht ein Tippfehler oder
Beistrich zu aendern. Ich lese es ganz begeistert, weil da einiges
drinnen ist, das ich noch nie gehoert habe. Und jetzt habe ich ein
Beispiel dazu mit meinem Tabellen.


Test erster Aufruf:
Es arbeitet mittelschnell.
Die Analyse sagt viele Zugriffe auf tbkurszeilen.

Die Ausgabe sieht leider so aus wie unten:
Es werden mehr als 3 COMM ausgeben.
AD ist nur zufaellig richtig, weil ich nur 3 habe.

verhext!


Nicole


COMM FK_JDATUM OPENINTEREST
AD 15.09.2009 104.735
AD 15.09.2009 29
AD 15.09.2009 15
BO 15.09.2009 123.843
BO 15.09.2009 27.307
BO 15.09.2009 24.998
BO 15.09.2009 15.529
BO 15.09.2009 10.108
BO 15.09.2009 8.831
BO 15.09.2009 8.073
BO 15.09.2009 841
BO 15.09.2009 446
BO 15.09.2009 430
BO 15.09.2009 2
BP 15.09.2009 67.036
BP 15.09.2009 98
BP 15.09.2009 20
BP 15.09.2009 2
C 15.09.2009 530.169
C 15.09.2009 139.975
C 15.09.2009 68.178
C 15.09.2009 65.651
C 15.09.2009 32.583
C 15.09.2009 12.388
C 15.09.2009 5.569
C 15.09.2009 1.979
C 15.09.2009 1.452
C 15.09.2009 745
C 15.09.2009 221
C 15.09.2009 162
C 15.09.2009 20
CC 15.09.2009 62.979
CC 15.09.2009 35.591
CC 15.09.2009 9.018
CC 15.09.2009 4.256
CC 15.09.2009 3.809
CC 15.09.2009 3.367
CC 15.09.2009 1.983
CC 15.09.2009 1.981
CD 15.09.2009 87.519
CD 15.09.2009 1.179
CD 15.09.2009 360
CD 15.09.2009 260
CD 15.09.2009 15
CL 15.09.2009 274.811
CL 15.09.2009 170.254
CL 15.09.2009 111.923
CL 15.09.2009 104.810
CL 15.09.2009 79.862
CL 15.09.2009 57.366
CL 15.09.2009 31.746
CL 15.09.2009 29.188
CL 15.09.2009 28.358
CL 15.09.2009 18.448
CL 15.09.2009 14.965
CL 15.09.2009 14.480
CL 15.09.2009 13.206
CL 15.09.2009 11.217
CL 15.09.2009 9.908
1
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
CL 15.09.2009 243
CR 15.09.2009 800
CR 15.09.2009 423
CT 15.09.2009 96.629
CT 15.09.2009 26.240
CT 15.09.2009 3.984
CT 15.09.2009 3.511
CT 15.09.2009 3.242
CT 15.09.2009 770
CT 15.09.2009 61
CT 15.09.2009 33
CT 15.09.2009 4
CU 15.09.2009 155.919
CU 15.09.2009 550
CU 15.09.2009 52
CU 15.09.2009 1
ED 15.09.2009 6.384.711
ED 15.09.2009 6.384.711
ED 15.09.2009 6.384.711
ED 15.09.2009 991.182
ED 15.09.2009 974.284
ED 15.09.2009 856.519
ED 15.09.2009 752.621
ED 15.09.2009 667.766
ED 15.09.2009 3.944
ED 15.09.2009 1.670
ED 15.09.2009 628
ED 15.09.2009 523
ED 15.09.2009 433
ED 15.09.2009 295
ED 15.09.2009 156
ES 15.09.2009 2.093.060
ES 15.09.2009 991.882
ES 15.09.2009 209
ES 15.09.2009 9
ES 15.09.2009 0
GC 15.09.2009 474.408
GC 15.09.2009 474.408
GC 15.09.2009 342.494
GC 15.09.2009 21.877
GC 15.09.2009 21.572
GC 15.09.2009 20.453
GC 15.09.2009 12.418
GC 15.09.2009 12.060
GC 15.09.2009 7.733
GC 15.09.2009 3.769
GC 15.09.2009 812
GC 15.09.2009 779
GC 15.09.2009 447
GC 15.09.2009 121
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 119.358
HG 15.09.2009 89.155
HG 15.09.2009 12.631
HG 15.09.2009 2.425
HG 15.09.2009 2.289
2
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
HG 15.09.2009 2.123
HG 15.09.2009 1.497
HG 15.09.2009 1.477
HG 15.09.2009 752
HG 15.09.2009 195
HG 15.09.2009 42
HG 15.09.2009 6
HO 15.09.2009 57.768
HO 15.09.2009 53.994
HO 15.09.2009 41.245
HO 15.09.2009 30.452
HO 15.09.2009 21.871
HO 15.09.2009 16.860
HO 15.09.2009 15.842
HO 15.09.2009 15.595
HO 15.09.2009 11.988
HO 15.09.2009 11.342
HO 15.09.2009 6.605
HO 15.09.2009 5.803
HO 15.09.2009 4.723
HO 15.09.2009 4.349
HO 15.09.2009 4.079
HO 15.09.2009 3.092
HO 15.09.2009 2.660
HO 15.09.2009 2.184
HO 15.09.2009 1.446
HO 15.09.2009 1.268
HO 15.09.2009 1.016
HO 15.09.2009 730
HO 15.09.2009 708
HO 15.09.2009 308
HO 15.09.2009 300
HO 15.09.2009 259
HO 15.09.2009 200
HO 15.09.2009 139
HO 15.09.2009 90
HO 15.09.2009 62
HO 15.09.2009 39
HO 15.09.2009 3
HO 15.09.2009 2
JY 15.09.2009 108.363
JY 15.09.2009 73
JY 15.09.2009 1
JY 15.09.2009 1
KC 15.09.2009 64.633
KC 15.09.2009 16.397
KC 15.09.2009 8.373
KC 15.09.2009 2.591
KC 15.09.2009 2.315
KC 15.09.2009 1.627
KC 15.09.2009 206
KC 15.09.2009 54
KC 15.09.2009 31
KC 15.09.2009 26
KC 15.09.2009 4
NG 15.09.2009 147.133
NG 15.09.2009 122.410
NG 15.09.2009 72.545
NG 15.09.2009 67.991
3
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
NG 15.09.2009 43.383
NG 15.09.2009 38.974
NG 15.09.2009 24.749
NG 15.09.2009 24.642
NG 15.09.2009 21.100
NG 15.09.2009 13.538
NG 15.09.2009 11.100
NG 15.09.2009 10.440
NG 15.09.2009 8.888
NG 15.09.2009 8.539
NG 15.09.2009 6.392
NG 15.09.2009 1.990
NG 15.09.2009 1.562
NG 15.09.2009 679
NG 15.09.2009 394
NG 15.09.2009 336
NG 15.09.2009 180
NG 15.09.2009 167
NG 15.09.2009 131
NG 15.09.2009 122
NG 15.09.2009 116
NG 15.09.2009 109
NG 15.09.2009 99
NG 15.09.2009 97
NG 15.09.2009 96
NG 15.09.2009 95
NG 15.09.2009 91
NG 15.09.2009 89
NG 15.09.2009 88
NG 15.09.2009 68
NG 15.09.2009 31
NG 15.09.2009 22
NG 15.09.2009 19
NG 15.09.2009 18
NG 15.09.2009 17
NG 15.09.2009 13
NG 15.09.2009 6
NG 15.09.2009 6
NG 15.09.2009 4
NG 15.09.2009 2
NG 15.09.2009 2
NG 15.09.2009 1
NQ 15.09.2009 240.087
NQ 15.09.2009 173.035
NQ 15.09.2009 12
O 15.09.2009 11.961
O 15.09.2009 2.134
O 15.09.2009 8
O 15.09.2009 4
OJ 15.09.2009 23.128
OJ 15.09.2009 2.889
OJ 15.09.2009 2.193
OJ 15.09.2009 443
OJ 15.09.2009 180
OJ 15.09.2009 85
OJ 15.09.2009 1
PL 15.09.2009 21.016
PL 15.09.2009 7.915
PL 15.09.2009 120
4
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
RB 15.09.2009 62.268
RB 15.09.2009 50.402
RB 15.09.2009 31.072
RB 15.09.2009 18.893
RB 15.09.2009 9.597
RB 15.09.2009 6.365
RB 15.09.2009 6.238
RB 15.09.2009 5.155
RB 15.09.2009 3.895
RB 15.09.2009 2.838
RB 15.09.2009 1.438
RB 15.09.2009 1.308
RB 15.09.2009 1.202
RB 15.09.2009 918
RB 15.09.2009 686
RB 15.09.2009 36
S 15.09.2009 254.267
S 15.09.2009 66.037
S 15.09.2009 32.070
S 15.09.2009 28.099
S 15.09.2009 24.967
S 15.09.2009 23.363
S 15.09.2009 922
S 15.09.2009 338
S 15.09.2009 258
S 15.09.2009 201
S 15.09.2009 111
S 15.09.2009 40
S 15.09.2009 15
SB 15.09.2009 315.521
SB 15.09.2009 155.121
SB 15.09.2009 113.510
SB 15.09.2009 74.022
SB 15.09.2009 68.394
SB 15.09.2009 44.505
SB 15.09.2009 14.189
SB 15.09.2009 13.215
SB 15.09.2009 11.540
SB 15.09.2009 8.880
SB 15.09.2009 3.169
SB 15.09.2009 2.506
SF 15.09.2009 44.927
SF 15.09.2009 80
SI 15.09.2009 94.750
SI 15.09.2009 10.337
SI 15.09.2009 3.734
SI 15.09.2009 2.900
SI 15.09.2009 2.808
SI 15.09.2009 2.314
SI 15.09.2009 339
SI 15.09.2009 141
SI 15.09.2009 3
SM 15.09.2009 77.583
SM 15.09.2009 28.217
SM 15.09.2009 13.060
SM 15.09.2009 12.376
SM 15.09.2009 11.509
SM 15.09.2009 7.696
SM 15.09.2009 4.967
5
25.02.2011 16:18:10
COMM FK_JDATUM OPENINTEREST
SM 15.09.2009 2.113
SM 15.09.2009 1.984
SM 15.09.2009 1.133
SM 15.09.2009 93
SM 15.09.2009 52
SM 15.09.2009 35
SM 15.09.2009 11
SP 15.09.2009 321.652
SP 15.09.2009 144.251
SP 15.09.2009 4.271
SP 15.09.2009 181
SP 15.09.2009 0
TY 15.09.2009 1.060.718
TY 15.09.2009 33.871
US 15.09.2009 729.357
US 15.09.2009 15.068
US 15.09.2009 158
W 15.09.2009 203.716
W 15.09.2009 44.912
W 15.09.2009 44.653
W 15.09.2009 16.336
W 15.09.2009 7.632
W 15.09.2009 893
W 15.09.2009 727
W 15.09.2009 52
W 15.09.2009 41
W 15.09.2009 16
6
25.02.2011 16:18:10
Sascha Adams
2011-02-25 09:19:47 UTC
Permalink
Ich habe da mal ein wenig mit Firebird gespielt und leider merkwürdiges
herausgefunden.

Gegeben seinen 2 Tabellen Kontrakte und Kurszeilen (man möge mir
verzeihen, daß ich hier die Beispiele aus dem Thread etwas
durcheinander werfe).

Kontrakte:

ID NAME
1 Hemd
2 Bluse
3 Hose
4 Rock

Kurszeilen:

ID COMM PREIS
1 1 11,99
2 1 12,99
3 1 13,99
4 1 10
5 2 5
6 2 6
7 2 7
8 2 1


Abfrage: (hier ist der Join auf die Kontrakte nicht enthalten, da er
für den Test als solchen erstmal nicht wirklich wichtig ist)

select z.id as zid,
z.comm as zcomm,
z.preis as zpreis,
from kurszeilen z
where exists (select first 3 z_sub.id from kurszeilen z_sub where
z_sub.comm=z.comm order by z_sub.preis desc)


Der Subselect herausgenommen und mit einer ID=1 gefüllt liefert das
gewünschte Ergebnis.

select first 3 z_sub.id from kurszeilen z_sub where z_sub.comm=1 order
by z_sub.preis desc

ID
3
2
1

Mit ID=2 ebenso.

select first 3 z_sub.id from kurszeilen z_sub where z_sub.comm=2 order
by z_sub.preis desc

ID
7
6
5

Führt man nun die komplette Abrfage wie oben gezeigt aus, dann kommt
folgendes unerwartete Ergebnis heraus.

ZID ZCOMM ZPREIS
1 1 11,99
2 1 12,99
3 1 13,99
4 1 10
5 2 5
6 2 6
7 2 7
8 2 1

Mein Schluß aus diesem Ergebnis ist, daß der IN Operator mit dem FIRST
im Subselect im Firebird scheinbar nicht klar kommt.

Diese Tests sind mit dem Firebird 1.5x gemacht. Inwieweit dies mit
neueren Version evtl. korrekt funktioniert kann ich hier gerade nicht
testen.


Als Randhinweis hier noch kurz, daß ein Tabellen-Alias ohne AS
definiert werden muß und ein Feldalias mit AS. Das scheint mir bisher
eines der Probleme von Nicole gewesen zu sein.

Evtl. hat hier ja jemand noch eine Idee, wie man dem Firebird das
korrekt unterjubeln kann.


Hier noch das SQL-Skript für die DB zum Test.

/* SQL Manager 2005 for InterBase/Firebird 4.4.0.2 */
/* ----------------------------------------------- */
/* Host : ISGSRV12 */
/* Database : C:\STP\DB\TEST.FDB */


CREATE DATABASE 'ISGSRV12:C:\STP\DB\TEST.FDB' USER 'SYSDBA'
PAGE_SIZE 4096;


/* Definition for the `KONTRAKTE_ID_GEN` generator : */

CREATE GENERATOR KONTRAKTE_ID_GEN;

SET GENERATOR KONTRAKTE_ID_GEN TO 4;

/* Definition for the `KURSZEILEN_ID_GEN` generator : */

CREATE GENERATOR KURSZEILEN_ID_GEN;

SET GENERATOR KURSZEILEN_ID_GEN TO 8;


/* Structure for the `KONTRAKTE` table : */

CREATE TABLE KONTRAKTE (
ID INTEGER NOT NULL,
NAME VARCHAR(20) CHARACTER SET WIN1251 DEFAULT '' NOT NULL COLLATE
WIN1251);


ALTER TABLE KONTRAKTE ADD PRIMARY KEY (ID);



/* Structure for the `KURSZEILEN` table : */

CREATE TABLE KURSZEILEN (
ID INTEGER NOT NULL,
COMM INTEGER DEFAULT 0 NOT NULL,
PREIS NUMERIC(15, 2) DEFAULT 0.0 NOT NULL);


ALTER TABLE KURSZEILEN ADD PRIMARY KEY (ID);



/* Data for the `KONTRAKTE` table (Records 1 - 4) */

INSERT INTO KONTRAKTE
VALUES (1, 'Hemd');

INSERT INTO KONTRAKTE
VALUES (2, 'Bluse');

INSERT INTO KONTRAKTE
VALUES (3, 'Hose');

INSERT INTO KONTRAKTE
VALUES (4, 'Rock');

COMMIT WORK;

/* Data for the `KURSZEILEN` table (Records 1 - 8) */

INSERT INTO KURSZEILEN
VALUES (1, 1, 11.99);

INSERT INTO KURSZEILEN
VALUES (2, 1, 12.99);

INSERT INTO KURSZEILEN
VALUES (3, 1, 13.99);

INSERT INTO KURSZEILEN
VALUES (4, 1, 10);

INSERT INTO KURSZEILEN
VALUES (5, 2, 5);

INSERT INTO KURSZEILEN
VALUES (6, 2, 6);

INSERT INTO KURSZEILEN
VALUES (7, 2, 7);

INSERT INTO KURSZEILEN
VALUES (8, 2, 1);

COMMIT WORK;

/* Definition for the `BI_KONTRAKTE_ID` trigger : */

SET TERM ^ ;

CREATE TRIGGER BI_KONTRAKTE_ID FOR KONTRAKTE
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(KONTRAKTE_ID_GEN, 1);
END^

SET TERM ; ^

/* Definition for the `BI_KURSZEILEN_ID` trigger : */

SET TERM ^ ;

CREATE TRIGGER BI_KURSZEILEN_ID FOR KURSZEILEN
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(KURSZEILEN_ID_GEN, 1);
END^

SET TERM ; ^
Sascha Adams
2011-02-25 09:28:18 UTC
Permalink
Post by Sascha Adams
Abfrage: (hier ist der Join auf die Kontrakte nicht enthalten, da er
für den Test als solchen erstmal nicht wirklich wichtig ist)
select z.id as zid,
z.comm as zcomm,
z.preis as zpreis,
from kurszeilen z
where exists (select first 3 z_sub.id from kurszeilen z_sub where
z_sub.comm=z.comm order by z_sub.preis desc)
Diese Abfrage ist natürlich prompt die falsche, die korrekte ist:

select z.id as zid,
z.comm as zcomm,
z.preis as zpreis,
from kurszeilen z
where z.id in (select first 3 z_sub.id from kurszeilen z_sub where
z_sub.comm=z.comm order by z_sub.preis desc)

Ändert aber am Ergebnis leider nichts.
Sascha Adams
2011-03-01 13:27:23 UTC
Permalink
Post by Sascha Adams
select z.id as zid,
z.comm as zcomm,
z.preis as zpreis,
from kurszeilen z
where z.id in (select first 3 z_sub.id from kurszeilen z_sub where
z_sub.comm=z.comm order by z_sub.preis desc)
Mit folgender Abfrage bekomme ich das gewünschte Ergebnis, allerdings
wird diese mit 3 Subselects wohl nur mit ordentlichen Indizes zu
Performance gelangen. Immer vorausgesetzt wir reden von einer
hinreichend großen Datenmenge. Aber das war ja aus den vorigen Posts
herauszulesen.

select z.id as zid,
z.comm as zcomm,
z.preis as zpreis,
from kurszeilen z
where z.id = (select first 1 z_sub.id from kurszeilen z_sub where
z_sub.comm=z.comm order by z_sub.preis desc)
or z.id = (select first 1 skip 1 z_sub.id from kurszeilen z_sub
where z_sub.comm=z.comm order by z_sub.preis desc)
or z.id = (select first 1 skip 2 z_sub.id from kurszeilen z_sub
where z_sub.comm=z.comm order by z_sub.preis desc)



--
Sascha Adams

Nicole Wagner
2011-02-25 16:07:34 UTC
Permalink
Post by Sascha Adams
Mein Schluß aus diesem Ergebnis ist, daß der IN Operator mit dem FIRST
im Subselect im Firebird scheinbar nicht klar kommt.
Diese Tests sind mit dem Firebird 1.5x gemacht. Inwieweit dies mit
neueren Version evtl. korrekt funktioniert kann ich hier gerade nicht
testen.
Ich habe Firebird 2.1.
Und ich habe langsam auch den Verdacht.
Post by Sascha Adams
Als Randhinweis hier noch kurz, daß ein Tabellen-Alias ohne AS
definiert werden muß und ein Feldalias mit AS. Das scheint mir bisher
eines der Probleme von Nicole gewesen zu sein.
Das glaube ich bei Version 2.1. nicht.
Denn ich habe beides probiert: as hinzuzufuegen oder wegzulassen.
Sowohl bei Tabellen als auch bei Feldnamen.
Es schien mir ident.

Eine sehr unangenehme Huerde jedoch war mir, dass ein Alias rueckwirkt.
D.h. dass ich oberhalb vom Alias die Tabelle ebenfalls nur mit dem
Alias ansprechen konnte statt auch mit dem urspruenglichen Namen. Wenn
ich in die Joins hineinging, galt das fuer jedes subselect jeweils
analog.

Wenn man das weiss, geht es ja.
Ich wusste es jedoch bis vor 2 Tagen nicht und habe viel Zeit damit
zugebracht, die Fehlermeldungen zu raetseln. Zudem mein IBExperts die
urspruenglichen Tabellennamen sogar in die Vervollstaendigenzeilen
schrieb und als gueltig einfaerbte.


Nicole
Thomas G. Liesner
2011-02-17 15:27:59 UTC
Permalink
Post by Nicole Wagner
Post by Thomas G. Liesner
Select * from blusen bl
where id in
(select id from blusen where farbe=bl.farbe
order by preis desc limit 3)
order by farbe, preis desc
Leider nein!
1) Mein Firebird Dialekt 3 kennt kein "limit" beim Sortieren
Daher die Anmerkung: "bzgl. des limit ggf. Anpassung an konkrete DB
nötig". Eine andere Sprachvariante ist "top", keine Ahnung, was Firebird
da nutzt - na gut, 1 Minute Googlen habe ich mir noch gegönnt, bei
Firebird/Interbase lautet die Syntax

Select first 3 ...

Schaffst du den Umbau selber oder brauchst du dazu auch wieder Hilfe?
Post by Nicole Wagner
2) es darf innerhalb der select-Anweisungsklammer kein order stehen.
Steht ja auch nicht. Das order by steht in einer syntaktisch
unabhängigen Subquery.
Post by Nicole Wagner
Stets sehe ich die Limitierung auf 3 der Gesamtabfrage.
Ich hingegen will die 3-Limitierung angewandt auf die JEWEILIGE
Unterabfrage.
Genau das habe ich formuliert.

So long,
Thomas G. Liesner
Loading...