![]() |
Datenbank: firerbird • Version: 2.1 • Zugriff über: ??
bin am verzweifeln... select abfragen miteinander kombinieren???
hallo, ich bin neu hier. habe aber schon viel durch euer forum gelernt. ich bin seit 8 wochen praktikant in einer firma, die ausschließlich mit delphi arbeitet und habe vorher nur java gemacht. so musste ich mir das meiste was delphi und auch sql angeht selbst beibringen. meine aufgabe in der firma ist es, eine bilderdatenbank zu erstellen mit benutzeroberfläche, in der die firma ihre icons dann zentral verwalten kann. sie besteht aus den tabellen bilder, tags und programme. jedes bild kann also verschiedenen tags und verschiedenen programmen zugeordnet werden, was ich durch zwei zusätzliche zwischentabellen gelöst habe. soweit so gut...
nun habe ich heute mein programm vorgestellt und es wurde angemahnt, dass man die db entweder nach bildern, programmen oder tags durchsuchen kann, was ich mit radiobuttons implementiert hatte. folgendermaßen sah meine anzeigen prozedur dann aus:
Delphi-Quellcode:
procedure anzeigen(parameter, befehl: String);
begin dm.dsetbilder.Close; dm.dsetbilder.SelectSQL.Clear; if befehl = 'alleanzeigen' then begin dm.dsetbilder.SelectSQL.Add('select * from bilder b order '+ 'by upper(b.name)'); end else begin // nach bild suchen if parameter = 'n' then dm.dsetbilder.SelectSQL.Add('select * from bilder b where upper(b.name)'+ ' containing upper(:WERT) order by upper(b.name)'); // nach programm suchen if parameter = 'p' then dm.dsetbilder.SelectSQL.Add('select * from bilder b where b.bid in '+ '(select b1.bid from BILDER b1 ' + 'join zwbilderprogramme z on z.bildid = b1.bid join programme t '+ 'on t.pid = z.programmid ' + 'where Upper(t.namep) containing UPPER(:WERT)) order by upper(b.name)'); // nach tag suchen if parameter = 't' then dm.dsetbilder.SelectSQL.Add('select * from bilder b where b.bid in '+ '(select b1.bid from BILDER b1 ' + 'join zwbildertags z on z.bildid = b1.bid join tags t on t.tid = z.tagid '+ 'where Upper(t.namet) containing UPPER(:WERT)) order by upper(b.name)'); dm.dsetbilder.ParamByName('WERT').AsString := befehl; end; dm.dsetbilder.Open; dm.dsetbilder.Locate('bid',bid2,[]); if dm.dsetbilder.IsEmpty then showmessage('Keine Icons gefunden'); end; das hat auch alles wunderbar funktioniert, bis mir mein chef heute sagte, ich solle die suche über checkboxen implementieren, so dass man z. b. gleichzeitig nach bild und tag suchen kann und nun bin ich mit meinem latein am ende... :( weiß jemand wie man dieses problem lösen kann? wäre dankbar für jeden denkanstoß. |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Du musst den Inhalt der where-clause dynamisch zusammenbasteln
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Wie wäre es mit einem Basis-Statement, das je nach Zustand der Checkboxen dynamisch erweitert werden kann?
Delphi-Quellcode:
So in der Art zumindest.
Dings.SQL.Text := 'SELECT * FROM Bilder WHERE 1 = 1';
if cbBla.Checked then begin Dings.SQL.Add('AND Bla = :blubb'); Dings.ParamByName('blubb').Value := edtWuppdi.Text; end; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Zitat:
Soll "KILLEFIT" in Programmen und in Tags und in Bildern gesucht werden ? Oder ist Bild="KILLEFIT" und Programm="SELBSTZERSTÖRER" oder ist Bild="KILLEFIT" und Programm="Selbszerstörer" oder Tags="Selbstzerstörer" oder..... Was soll denn da möglich sein? Gruß K-H |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Ideal wäre, wenn Du die Tabellen ordentlich aufgebaut hast, also der Index und das zu durchsuchende Textfeld überall gleich heißen.
Dein Freund dürfte, zumindest in MySQL, ![]() |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
möglich sein soll, dass man mit einem suchbegriff sowohl in den bildern an sich als auch die bilder, die mit dem jeweiligen tag oder programm, dass diesen suchbegriff trägt, in verbindung stehen, angezeigt bekommt.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Also Du gibst einen Suchbegriff ein und daraufhin soll ggf. in mehreren Feldern gesucht werden? In dem Fall kannst Du das auch so machen wie weiter oben beschrieben, nur dass statt dem AND dann ein OR verwendet werden muss.
[edit] Allerdings muss das ganze dynamische SQL dann in Klammern, da Du sonst immer alle DS gelistet bekommst. [/edit] [edit2] Kurz nachgedacht (ungetestet, geht ja nur ums Prinzip):
Delphi-Quellcode:
[/edit2]
const
ClauseBegins: array[Boolean] of string = ('WHERE', 'OR'); var HasWhere: Boolean; begin HasWhere := false; Query.SQL.Text := 'SELECT * FROM Bilder'; if cbBla.Checked then begin Query.SQL.Add(Format('%s Dings = :Dings', [ClauseBegins[HasWhere]])); Query.ParamByName(':Dings').Value := EditHallo.Text; HasWhere := true; end; if cbBlubb.Checked then begin Query.SQL.Add(Format('%s Bums = :Bums', [ClauseBegins[HasWhere]])); Query.ParamByName(':Bums').Value := EditHallo.Text; HasWhere := true; end; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
so vielen dank erstmal an alle. wollte jetzt das von deddyh ausprobieren doch spätestens wenn ich das zweite kästchen anclicke bekomme ich die fehlermeldung:
dynamic sql error code = -104 as approximate floating-point values in sql dialect1, but as 64-bit. weiß jemand was das bedeutet? hab ich das jetzt richtig eingebaut?
Delphi-Quellcode:
[CODE]
procedure anzeigen(n,p,t: boolean; befehl: String); var bid2: String; haswhere: boolean; const ClauseBegins: array[Boolean] of string = ('WHERE', 'OR'); begin bid2:= bid; dm.dsetbilder.Close; dm.dsetbilder.SelectSQL.Clear; if befehl = 'alleanzeigen' then begin dm.dsetbilder.SelectSQL.Add('select * from bilder b order '+ 'by upper(b.name)'); end else begin haswhere:= false; dm.dsetbilder.SelectSQL.Text:= 'SELECT * FROM Bilder b '; if n then begin dm.dsetbilder.SelectSQL.Add(Format('%s name containing upper(:WERT)', [ClauseBegins[HasWhere]])); HasWhere := true; end; if p then dm.dsetbilder.SelectSQL.Add(Format(' %s (select * from bilder c where c.bid in '+ '(select c1.bid from BILDER c1 ' + 'join zwbilderprogramme z on z.bildid = c1.bid join programme t '+ 'on t.pid = z.programmid ' + 'where Upper(t.namep) containing UPPER(:WERT)))', [ClauseBegins[HasWhere]])); HasWhere := true; if t then dm.dsetbilder.SelectSQL.Add(Format(' %s (select * from bilder b where b.bid in '+ '(select b1.bid from BILDER b1 ' + 'join zwbildertags z on z.bildid = b1.bid join tags t on t.tid = z.tagid '+ 'where Upper(t.namet) containing UPPER(:WERT)))', [ClauseBegins[HasWhere]])); dm.dsetbilder.ParamByName('WERT').AsString := befehl; end; dm.dsetbilder.Open; dm.dsetbilder.Locate('bid',bid2,[]); showmessage(dm.dsetbilder.SelectSQL.Text); if dm.dsetbilder.IsEmpty then showmessage('Keine Icons gefunden'); end; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Schon beim Anklicken? Zeig doch mal Deinen Code.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Benutz doch bitte die Delphi-Tags. Was mir auffällt: sobald der Subselect ins Spiel kommt, dürfte das ganze Statement nicht mehr stimmen. Lass Dir doch zur Kontrolle einmal den gesamten m.dsetbilder.SelectSQL.Text ausgeben.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
ich krieg ja schon beim 2. diese fehlermeldung. da brauch ich aber die zwischentabellen. ohne die geht es leider nicht, aber irgendwas mache ich da syntaktisch falsch ich weiß bloß nicht was?
ich weiß ich bin ein schwieriger fall aber bin ja noch relativ anfänger... |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Der 2. (if p then) ist ja bereits der Subselect, da fehlt doch noch etwas. Wie gesagt, lass Dir das komplette Statement zur Kontrolle ausgeben.
Delphi-Quellcode:
Übrigens gibt es auch Delphi-Tags (die Schaltfläche mit dem Helm), dann sind auch die Hervorhebungen dabei.
ShowMessage(dm.dsetbilder.SelectSQL.Text); //ggf. erstmal ein exit; hierhin
dm.dsetbilder.Open; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Wie wäre es denn mit einem View?
etwa so:
Code:
so könnte man ein einheitliches Mäntelchen über die unterschiedlichen Tabellen legen.
select 'Bild',Bild.ID,Bild.Name from Bild
union select 'Tag',Tag.ID,Tag.Name from Tag union select 'Prog',Programme.ID,Programme.Name Gruß K-H |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
@p80286
ich suche ja nicht in den mastertabellen sondern in den zwischentabellen, deswegen ist das ja so schwierig. @deddyh und ich kann mir den befehl gar nicht ausgeben lassen weil er sich schon gar nicht adden lässt :( |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Wie, lässt sich nicht adden? In diesem Moment ist das doch nichts anderes als eine stinknormale Stringliste. Zur Not kannst Du aber auch temporär eine solche erzeugen, das Statement dort zusammenbauen, Dir das Ergebnis ausgeben lassen, bei Gefallen dem SQL der Query zuweisen und diese ausführen.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
ok war mein fehler. habs jez in ein memo gepackt
SELECT * FROM Bilder b WHERE name containing upper(:WERT) OR (select * from bilder c where c.bid in (select c1.bid from BILDER c1 join zwbilderprogramme z on z.bildid = c1.bid join programme t on t.pid = z.programmid where Upper(t.namep) containing UPPER(:WERT))) |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Das sieht irgendwie unnötig kompliziert aus. Was genau bezweckst Du denn mit dem Subselect? Außerdem: fehlt da nicht ein EXISTS vor der Klammer?
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
ich bin leider noch nicht so firm in sql daher frage ich ja. diese struktur muss sein da ich die verbindung über zwtabelle und mastertabelle herstellen muss. nur wie ich die beiden selects syntaktisch richtig miteinander verknüpfe, weiß ich nicht. jede für sich alleine tut genau was sie soll.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
So soll es doch am Ende aussehen, oder?
SQL-Code:
[edit] Müsste das nicht das Gleiche sein wie
SELECT * FROM bilder b
WHERE UPPER(b.name) CONTAING UPPER(:WERT) OR b.bid IN ( --b.bid IN fehlt bei Dir SELECT * FROM bilder c WHERE c.bid IN ( SELECT c1.bid FROM BILDER c1 JOIN zwbilderprogramme z ON z.bildid = c1.bid JOIN programme t ON t.pid = z.programmid WHERE UPPER(t.namep) CONTAING UPPER(:WERT) ) )
SQL-Code:
:?:[/edit]
SELECT * FROM bilder b
WHERE UPPER(b.name) CONTAING UPPER(:WERT) OR EXISTS ( SELECT * FROM zwbilderprogramme z JOIN programme t ON t.pid = z.programmid WHERE z.bildid = b.bid AND UPPER(t.namep) CONTAING UPPER(:WERT) ) |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Delphi-Quellcode:
jetzt kriege ich den fehler: count of column list and variable list do not match
SELECT * FROM Bilder b
WHERE name containing upper(:WERT) OR b.bid IN ( SELECT * FROM bilder c WHERE c.bid IN ( SELECT c1.bid FROM BILDER c1 JOIN zwbilderprogramme z ON z.bildid = c1.bid JOIN programme t ON t.pid = z.programmid WHERE UPPER(t.namep) CONTAINing UPPER(:WERT))) |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Jepp, der Stern im Subselect ist falsch, da darf man natürlich nur die Id abfragen. Hast Du mal das Statement aus meinem Edit versucht?
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Oder eine Kombination aus DeddyH und p80286 Vorschlägen. Erst eine View erzeugen, in der über Joins und/oder Unions eine "bei mir steht alles drin"-Tabelle/View gebildet wird.
Auf den kann dann ein ganz einfaches Select geschossen werden, wo immer nur eine Bedingung angehängt wird, sinngemäß:
Delphi-Quellcode:
i:=0
SQL.Add := 'Select * From tabelle'; if cb1.checked then begin i:=i+1; if i=0 then SQL.Add := 'Where' else SQL.Add := 'Or' SQL.Add 'Feldname1 is like ''%(:Wert)%'')' end if cb2.checked then begin i:=i+1; if i=0 then SQL.Add := 'Where' else SQL.Add := 'Or' SQL.Add 'Feldname2 is like ''%(:Wert)%'')' end //usw. |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Wo liegt der Sinn in einer UNION, wenn ich nur die WHERE-Klausel erweitern muss? Es sei denn, ich will die Quelle unterscheiden wie von p80286 vorgeschlagen. Aber es kommt eben darauf an, wie das Ergebnis aussehen soll.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Zitat:
Gruß K-H |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Man kann das auch in Parameter verwursteln ( habe ich schon gemacht)
SQL-Code:
Statt NULL kann man natürlich auch einen anderen Wert nehmen (z.B. -1)
select
<Feldliste> from <Tabelle> where (( <Feld1 is null>) or (<Feld1> = :wert1)) or (( <Feld2 is null>) or (<Feld2> = :wert2)) ...; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
also habe jetzt mal die union variante ausprobiert, aber die funktioniert ja nur, wenn ich bei beiden abfragen genau die gleiche anzahl an spalten habe. das geht deshalb nicht weil ich in der ersten abfrage ja nur eine tabelle brauche und in der 2. schon 3...
werde jetzt mal den tipp von kinzler versuchen. danke an alle die mir versuchen zu helfen. hab noch bis morgen nachmittag zeit dann muss das programm stehen. :( |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Langsam zweifle ich daran, ob ich Dein Anliegen auch richtig verstanden habe. Daher frage ich lieber noch einmal nach: es soll so sein, dass Du z.B. in ein Edit "Hallo" eingibst und dann per Checkboxen festlegen willst, welche Felder nach diesem "Hallo" durchsucht werden sollen, ist das soweit richtig?
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Die Feldliste muss immer gleich viele Spalten haben und diese müssen die identischen Typen haben. Du kannst aber auch Dummy-Felder verwenden
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
@kinzler
könntest du das noch mal etwas näher erläutern? also sind die felder teil der feldliste? würde das mit tstringlist machen... |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
SQL-Code:
select
n.id, n.name, '' as Ort from namen n union select n.id, n.name, o.ort from namen n join orte o on o.plz = n.plz; |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
@deddyh
du hast es richtig verstanden. man sucht aber immer nach bildern, nie direkt nach programmen oder tags, sondern nur nach bildern, die über zwischentabellen mit den programmen/tags, die den suchbegriff enthalten, verbunden sind. habe jetzt etwas anderes probiert. ist zwar erstmal statisch aber habe erstmalig keinen sql fehler(!!!!) erhalten.:
Delphi-Quellcode:
das einzige problem dabei ist, dass ich nun die datensätze doppelt und dreifach sehe, wollte das mit distinct b.name lösen, aber das programm braucht ja auch die ganzen anderen felder aus der tabelle bilder.
if frmhaupt.CheckBox1.Checked and frmhaupt.CheckBox2.Checked and
not frmhaupt.CheckBox3.Checked then dm.dsetbilder.SelectSQL.Add('select * from zwbilderprogramme z, '+ 'bilder b, programme p '+ 'where b.bid=z.bildid and p.pid=z.programmid ' + 'and p.namep containing UPPER(:WERT) or b.name '+ 'containing upper(:WERT)'); |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Zitat:
Code:
Gruß
'where b.bid=z.bildid and p.pid=z.programmid ' +
'and (p.namep containing UPPER(:WERT) or b.name '+ 'containing upper(:WERT)')); K-H |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
super es funktioniert!!! dank der klammer! danke danke danke
endlich bin ich einen schritt weiter...
Delphi-Quellcode:
nun muss ich nur noch die anderen abfragen miteinander verbinden, mal schauen ob ich das hinkriegeif frmhaupt.CheckBox1.Checked and frmhaupt.CheckBox2.Checked and not frmhaupt.CheckBox3.Checked then dm.dsetbilder.SelectSQL.Add('select * from zwbilderprogramme z, '+ 'bilder b, programme p '+ 'where b.bid=z.bildid and p.pid=z.programmid ' + 'and (p.namep containing UPPER(:WERT) or b.name '+ 'containing upper(:WERT)) order by upper(b.name)'); |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Korrekt, AND hat eine stärkere Bindung als OR.
|
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
so habe mein neu erworbenes wissen jetzt versucht auf die anderen kombinationsmöglichkeiten zu übertragen, was schon teilweise funktionierte. leider gab er mir diesmal nur eine handvoll datensätze aus und ignorierte alle anderen... aber immerhin gabs keinen sql fehler :)
Delphi-Quellcode:
habe die lösung: ich habe nur 2 ds, die überhaupt mit einem tag verknüpft sind also zeigt es nur 2 an. ich würde aber gerne auch die anzeigen lassen, wo garkein tag verlinkt ist...// wenn nach bild und tag gesucht wird if frmhaupt.CheckBox1.Checked and not frmhaupt.CheckBox2.Checked and frmhaupt.CheckBox3.Checked then dm.dsetbilder.SelectSQL.Add('select * from zwbildertags x, '+ 'bilder b, tags t '+ 'where b.bid=x.bildid and t.tid=x.tagid ' + 'and (t.namet containing UPPER(:WERT) or b.name '+ 'containing upper(:WERT)) order by upper(b.name)'); // wenn nach programm und tag gesucht wird if not frmhaupt.CheckBox1.Checked and frmhaupt.CheckBox2.Checked and frmhaupt.CheckBox3.Checked then dm.dsetbilder.SelectSQL.Add('select * from zwbilderprogramme z, '+ 'bilder b, programme p,zwbildertags x, tags t '+ 'where b.bid=z.bildid and p.pid=z.programmid ' + 'and b.bid=x.bildid and t.tid=x.tagid '+ 'and (p.namep containing UPPER(:WERT) or t.namet '+ 'containing upper(:WERT)) order by upper(b.name)'); |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Im Moment machst Du einen INNER JOIN über 3 Tabellen, das bedeutet, dass Du nur DS gelistet bekommst, die über alle Tabellen verknüpft sind. Was Du also brauchst, ist ein OUTER JOIN.
SQL-Code:
Gibt es in Tabelle2 bzw. Tabelle3 keine entsprechenden DS, haben deren Felder dann durchgängig NULL-Werte.
SELECT
Feldliste FROM Tabelle1 A LEFT JOIN --oder auch LEFT OUTER JOIN, ist es aber automatisch Tabelle2 B ON B.FK = A.PK LEFT JOIN --oder auch LEFT OUTER JOIN, ist es aber automatisch Tabelle3 C ON C.FK = B.PK |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
super danke hab das halt mit der schreibweise mit diesem join noch nicht so ganz verinnerlicht. ich probiers mal...
allerdings hatte ich mit den joins immer sql fehler... mit dieser variante allerdings nicht. ist es evtl. möglich, einen mit dieser variante zu formulieren? z.b. mit or statt and? |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
In der
![]() |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
Sry, ich hatte das Edit nicht gesehen. Ja, das geht, das wäre dann Deine Where-Klausel.
SQL-Code:
SELECT
Feldliste FROM Tabelle1 A LEFT JOIN Tabelle2 B ON B.FK = A.PK --Verknüpfungsbedingung(en) WHERE A.Feld1 = 'Dings' OR B.Feld1 = 'Bums' --Filterbedingung(en) |
AW: bin am verzweifeln... select abfragen miteinander kombinieren???
aber da ist ja wieder das join drin... das muss doch auch ohne das join gehen...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz