Benutzer mit den meisten Antworten
Datenabfrage auf DataTable Problem

Frage
-
Hallo Leute ich stehe total auf dem schlauch, und zweifele gerade an meine Denklogik.
Ich habe eine DataTable mit folgenden Einträgen
RecNo | Kdnr | Datum | Suchfeld
1 3 01.01.2011 KLMD
3 5 02.01.2011 KLMD
7 3 10.01.2011 MDFR
10 7 10.01.2011 TREF
11 9 10.01.2011 KLMD
17 3 20.01.2011 TREFNun versuche ich über die DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND NOT Suchfeld Like 'TREF*') die Abfrage zu starten
Ich bekomme immer Kunde 3 Angezeigt der zwar die erste Bedingung erfüllt "KLMD" ist vorhanden, aber die zweite Bedingung nicht erfüllt "TREF" soll er nicht haben.
Wer gibt mit nachhilfe in Abfragen wäre wirklich sehr dankbar.
Gruß Thomas
Antworten
-
Hi Markus,Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.Eine Linq Anweisung muss nicht fest programmiert sein. Bei variablen Anforderungen kann man Expression Tress nutzen und damit dynamisch Abfragen “zusammenbasteln”.Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.Das ist nur eine Frage der Linq-Kenntnisse. Ich finde, dass Linq viel übersichtlicher ist, da die Abfrage kompakter nur an einer Stelle definiert wird anstelle einzelner Codezeilen in ggf. langen Code-Schleifen.--
Viele Grüße
Peter- Als Antwort markiert tommytom73 Mittwoch, 13. Juli 2011 09:17
Alle Antworten
-
Deine Abfrage ergibt als Ergebnis eine Menge aus drei Datensätzen, und zwar RecNo=1, 3 und 11.Du fragst: Gib mir bitte alle Datensätze, die das Datum vom '01.01.2011' bis zum '20.01.2011' haben UND das Suchfeld mit 'KLMD' beginnt UND das Suchfeld nicht mit 'TREF' beginnt. Das trifft beim Datensatz mit RecNo=1 zu.Was willst Du genau haben?--
Viele Grüße
Peter- Bearbeitet Peter Fleischer Dienstag, 28. Juni 2011 12:01
-
Hallo Peter Ich danke Dir das du dich mit dem Problem beschäftigst.
Ich brauche alle kunden die im Suchfeld "KLMD" haben, aber im gleichen Zeitraum keinen Eintrag "TREF" haben.
Ich denke man müsste ihm sagen das er nicht jede einzelne Zeile betrachten soll, sondern alle Zeilen des kunden in dem Zeitraum als eins. Aber wie ich das mache hab ich im moment keine Idee.
Wenn mir da jemand des rätsels lösung gibt wäre ich sehr erleichtert
Gruß Thomas
-
-
Hallo Peter
bekommt man das über Datatable.Select(...) hin oder sollte ich mich davon verabschieden?
Die Aufgabenstellung ist jetzt mal an diesem Beispiel festgemacht. Normalerweise baue ich die Abfrage dynamisch auf dort können ja noch andere Möglichkeiten zutreffen
Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND Suchfeld Like 'TREF*') '// Sollte problemlos gehen
Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' OR Suchfeld Like 'TREF*') '// Sollte eigentlich auch gehen
Bsp. DataTable.Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND Suchfeld Like 'TREF*' OR Suchfeld Like 'MDFR*)Würde ich mit LINQ besser hinkommen ?
Gruß Thomas
-
Hallo Thomas,
wegen Linq habe ich mal bei Holger Schwichtenberg und Rod Stephens nachgesehen:
Wenn das Datum bei dir vom Typ String ist wird die Abfrage nicht zuverlässig funktionieren.
("20.01.2011" wäre ja grösser als "10.02.2011". Hab deshalb im Beispiel den Datentyp Date verwendet.)
Dim dt As DataTable
dt = New DataTable
dt.Columns.Add("RecoNo", GetType(Integer))
dt.Columns.Add("Kdnr", GetType(Integer))
dt.Columns.Add("Datum", GetType(Date))
dt.Columns.Add("Suchfeld", GetType(String))
dt.Rows.Add(1, 3, #1/1/2011#, "KLMD")
dt.Rows.Add(3, 5, #1/2/2011#, "KLMD")
dt.Rows.Add(7, 3, #1/10/2011#, "MDFR")
dt.Rows.Add(10, 7, #1/10/2011#, "TREF")
dt.Rows.Add(11, 9, #1/10/2011#, "KLMD")
dt.Rows.Add(17, 3, #1/20/2011#, "TREF")
Dim a As IEnumerable
' Heraus kommen Kundennummer 5 und 9.
a = (From b In dt.AsEnumerable
Where b.Field(Of String)("Suchfeld") Like "KLMD*" _
And b.Field(Of Date)("Datum") >= #1/1/2011# _
And b.Field(Of Date)("Datum") <= #1/20/2011#
Select b.Field(Of Integer)("Kdnr")).Except _
(From b In dt.AsEnumerable
Where b.Field(Of String)("Suchfeld") Like "TREF*" _
Select b.Field(Of Integer)("Kdnr"))
End Sub
-
Geht das dynamisches Linq?
Ansonsten bleibt meiner Meinung nach der Ansatz von Peter über das SQL zum Füllen der DataTable.
Etwa:
"Select * from Kunden
where Suchfeld Like 'KLMD%'
and Datum >= '01/01/2011'
and Datum <= '01/20/2011'
and Kdnr not in
(Select Kdnr from Kunden where Suchfeld Like 'Tref%')"
-
Danke Markus
Dynamisches Linq wird nicht funktionieren, das hab ich gestern Abend mal durch gespielt. Aber Dein zweiter Hinweis mit der Select Anweisung sieht genau nach dem aus was ich suche. Ich werde es heute mal probieren.
Danke an euch 2 für die schnellen Ideen.
Gruß Thomas
-
tommytom73 schrieb:> Hallo Leute ich stehe total auf dem schlauch, und zweifele gerade an> meine Denklogik.>> Ich habe eine DataTable mit folgenden Einträgen>> RecNo | Kdnr | Datum | Suchfeld> 1 3 01.01.2011 KLMD> 3 5 02.01.2011 KLMD> 7 3 10.01.2011 MDFR> 10 7 10.01.2011 TREF> 11 9 10.01.2011 KLMD> 17 3 20.01.2011 TREF>> Nun versuche ich über die DataTable.Select(Datum>='01.01.2011' AND> Datum<='20.01.2011' AND Suchfeld Like 'KLMD*' AND NOT Suchfeld Like> 'TREF*') die Abfrage zu starten>> Ich bekomme immer Kunde 3 Angezeigt der zwar die erste Bedingung erfüllt> "KLMD" ist vorhanden, aber die zweite Bedingung nicht erfüllt "TREF"> soll er nicht haben.>Hallo Thomas,ich sehe da drei Probleme:1) Datumsangaben übergibst Du generell besser als typisierten Parameter2) Hier unter SQL 2008 R2 ergibt "Suchfeld Like 'KLMD*'" keineÜbereinstimmung, wenn der Name "KLMD" ist, weil ja nach einer längerenZeichenfolge gefraggt wurde3) "AND NOT Suchfeld Like 'TREF*')" trifft zu, wenn der Name "TREF" ist(denn "TREF" ist ungleich "TREF" + irgendwelche Zeichen.Also, versuche einmal:Select(Datum>='01.01.2011' AND Datum<='20.01.2011' AND Suchfeld='KLMD'AND Suchfeld <> 'TREF')GrußJohannes Busch
-
Hallo Johannes
Ist alles richtig was du sagst, wenn ich einen SQL-Server hätte!
Aber meine Frage bezog sich auf die DataTable die man auch kommplett offline betreiben kann. Mein Problem ist, da ich noch immer mit DBase Datenbanken arbeiten muss, und ich nicht die Datenzugriffstreiber nutzen kann, wegen dem gleichzeitigem Zugriff ("Codebase 6.5") fülle ich das Dataset über die native Codebase DLL mit den Daten die ich brauche. Und dann muss ich halt mit dynamischen Abfragen die Daten in dem Offline DataSet Filtern. Und dabei bleibt mir nur die "DataTable.Select("")" Funktion die mir aber dahingehen Kopfzerbrechen macht weil sie hat nicht so einleuchtend gestrickt ist wie eine SQL-Select Anweisung an einen SQL-Server, wenn man komplexe Abfrage macht.
Für mich stellt sich im Moment die Frage ob ich mir noch eine SQL-Server Express Datenbank ans Bein binde um die Daten die ich mit der Codebase.dll bekomme in die Express DB rüberlade um dann mit SP's oder Select Anweisungen die Daten Filtere. Im Moment bin ich ein wenig ratlos.
Gruß THomas
-
Wenn Du mit typisiertem DataSet arbeitest, kannst Du auch anstelle der Select-Methode LinQ nutzen. Da hast Du eine Vielzahl weiterer Möglichkeiten, vor allem auch einfacher. Den Umweg über eine zusätzliche Datenbank würde ich nicht gehen, wenn es dazu keine langfristige Notwendigkeit (z.B. Ablösung von dBase) gibt.--
Viele Grüße
Peter -
Ist denn wirklich ein dynamischer Select, also in einem String notwendig? D.h. das dieser Selectstring immer
erst vom Programm zusammengesetzt werden muss?Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.
Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.
-
Hi Markus,Wenn du das Selektieren über mehrere verschiedene Selectmethoden fest codieren kannst dann geht natürlich auch Linq.Eine Linq Anweisung muss nicht fest programmiert sein. Bei variablen Anforderungen kann man Expression Tress nutzen und damit dynamisch Abfragen “zusammenbasteln”.Oder auch eine While Schleife, die vermutlich besser zu verstehen ist.Das ist nur eine Frage der Linq-Kenntnisse. Ich finde, dass Linq viel übersichtlicher ist, da die Abfrage kompakter nur an einer Stelle definiert wird anstelle einzelner Codezeilen in ggf. langen Code-Schleifen.--
Viele Grüße
Peter- Als Antwort markiert tommytom73 Mittwoch, 13. Juli 2011 09:17
-
Danke an alle die sich mit dem Problem beschäftigt haben.
Ich war jetzt ein paar Tage nicht online deswegen schreibe ich erst jetzt. Ich habe erstmal eine Klasse geschrieben die den Vergleich auf "AND, AND NOT, OR, OR NOT und NOT" zu Fuss erledigt. Ich werde mich jetzt nochmal intensiv mit LINQ auseinander setzten um das jetzige Ergebnis noch mal Datenbank konform zu lösen, mit den DataTable.Select bin ich nicht richtig weiter gekommen.
Danke an Peter, Markus und Johannes
Grüße Thomas