Kann man berechnete Felder nicht in SQL-Anweisungen verwenden ?
Wenn ich z.B. Bestellnummern und Aktenzeichen habe, die bestimmten Erstellungsregeln folgen müssen (hier: die rechten zwei Zeichen des Aktenzeichens müssen am Anfang der Bestellnummer stehen), könnte ich mit folgender Abfrage die "Ausreißer" darstellen:
SELECT Tabelle1.Bestellnummer, Aktenzeichen, Left(Bestellnummer,2) AS Anfang, Right([Aktenzeichen],2) AS Ende
FROM Tabelle1
WHERE Left(Bestellnummer,2)<>Right(Aktenzeichen,2);
Dieser SQL-Ausdruck ist ja noch leicht zu überblicken, aber wenn die WHERE-Klausel komplizierter wäre, wäre es komfortabler, wenn man die Namen der oben definierten berechneten Felder "Anfang" und "Ende" verwenden könnte, statt die Definition nochmals zu wiederholen:
SELECT Tabelle1.Bestellnummer, Aktenzeichen, Left(Bestellnummer,2) AS Anfang, Right([Aktenzeichen],2) AS Ende
FROM Tabelle1
WHERE Anfang<>Ende;
Dieser Ausdruck führt aber zu einer Fehlermeldung, schade.
Oder geht das doch irgendwie ?
Du kannst Aliase (https://codekabinett.com/rdumps.php?Lang=1&targetDoc=sql-as-alias) leider nicht innerhalb derselben Abfrage(-ebene) verwenden in der sie definiert wurden.
Du kannst aber eine Abfrage erstellen die die Ausdrücke enthält und dann eine zweite, die auf dieser Abfrage aufsetzt und die Filterung vornimmt. Die erste Abfrage kann auch eine Subquery in der ersten sein.
Noch eine andere Überlegung: Wenn die ersten zwei Zeichen von Bestellnummer und Aktenzeichen immer identisch sein müssen, könnte man diese in einem separaten Feld "Präfix" speichern und in den beiden vorgenannten Feldern weglassen. Damit wäre solche Datenanomalien ausgeschlossen.
Ja, ich sehe das auch so: wenn in verschiedenen Feldern manche Zeichen identisch sein sollen, führt das fast zwangsläufig zu Inkonsistenzen. Leider wurde unsere Feldstruktur beim Aufbau der Datenbank nicht dokumentiert, so dass wir die exakten Bildungsregeln erst einmal herausfinden müssen.
Deshalb will ich
1.: durch Abfragen herausfinden, ob meine Annahmen für alle Datensätze zutreffen oder ob es noch weitere Varianten gibt und darauf aufbauend
2.: entscheiden, welche Felder / Feldteile redundant sind und entfallen können.
Meine Annahme für die Bildungsregeln ist (ich habe meine Eingangsannahme etwas erweitert,
dabei steht A für feste Zeichen, ### für eine Buchstaben-Dezimalgliederung variabler Länge und n für eine Zahl):
Aktenzeichen: AAA ### (z.B.: F05 A 5.1 oder F06 K 3.1.2)
Buchungszeichen: AAA ### AA.n (z.B.: F05 A 5.1 Nr. 6 oder F06 K 3.1.2 Nr. 12)
Prüffrage: sind die ### in beiden Feldern gleich ?
Deshalb habe ich eine Abfrage 1 erstellt (Felder und Teilfelder; WHERE, weil es Datensätze mit leerem Aktenzeichen gibt):
SELECT
Tabelle1.Aktenzeichen,
Left(Aktenzeichen,4) AS AZ_links,
Right(Aktenzeichen,Len(Aktenzeichen)-4) AS AZ_rechts,
Tabelle1.Bestellnummer,
Mid(Bestellnummer,5,Len(Aktenzeichen)-4) AS Nr_mitte
FROM Tabelle1
WHERE Tabelle1.Aktenzeichen >"";
Um Abweichungen von meiner Annahme aufzulisten, habe ich darauf aufbauend eine Abfrage 2 gemacht
(Datensätze, wo die Gliederung in beiden Feldern nicht übereinstimmt):
SELECT Abfrage1.Aktenzeichen, Abfrage1.AZ_links, Abfrage1.AZ_rechts, Abfrage1.Nr_mitte
FROM Abfrage1
WHERE Abfrage1.Nr_mitte<>Abfrage1.AZ_rechts;
Überraschenderweise lassen sich die Spalten aus Abfrage 2 nicht sortieren (Meldung: Verwendung von Null unzulässig) !
Die Spalten aus Abfrage 1 ließen sich alle sortieren. Die Felder sind Textfelder.
Was kann da dahinterstecken ?
Kannst Du mir ein Beispiel für eine Subquery schicken ? Damit hatte ich noch gar nichts zu tun.
ZitatBeispiel für eine Subquery
Grundlagen - SQL ist leicht (6) - Komplexe Abfragen schreiben und lesen (https://www.ms-office-forum.net/forum/showthread.php?p=1633105#post1633105)
Zitat
F06 K 3.1.2 Nr. 12
Es ist regelmäßig vorteilhaft, solche Ausdrücke nicht nur in einer Abfrage zu zerlegen, sondern diese dann atomaren Informationen in getrennten Tabellenfeldern zu speichern - und nebenbei eine Forderung der 1. Normalform zu erfüllen.
Warum?
- Wenn man den zusammengesetzten Ausdruck benötigt, ist es sehr viel einfacher, diesen aus mehreren Feldinhalten zusammenzusetzen, als umgekehrt jedesmalig eine Live-Trennung vorzunehmen. Deine Probleme sprechen für sich.
- Einzelinhalte sind leichter zu vergleichen.
- Bei Tabellenfeldern ohne aufgesetzte Berechnung lassen sich Indizes nutzen und somit Vergleiche, Sortierungen & Co. performanter gestalten.
Bei einer einmaligen Trennung in Einzelinhalte fällt es einem auch leichter, etwas mehr Aufwand zu treiben. Eine Buchstaben-Dezimalgliederung
variabler Länge kann man sehr geschickt über reguläre Ausdrücke erfassen.
Zitat von: nurmikss am März 07, 2019, 00:07:31
Kann man berechnete Felder nicht in SQL-Anweisungen verwenden ?
Wenn ich z.B. Bestellnummern und Aktenzeichen habe, die bestimmten Erstellungsregeln folgen müssen (hier: die rechten zwei Zeichen des Aktenzeichens müssen am Anfang der Bestellnummer stehen), könnte ich mit folgender Abfrage die "Ausreißer" darstellen:
SELECT Tabelle1.Bestellnummer, Aktenzeichen, Left(Bestellnummer,2) AS Anfang, Right([Aktenzeichen],2) AS Ende
FROM Tabelle1
WHERE Left(Bestellnummer,2)<>Right(Aktenzeichen,2);
Dieser SQL-Ausdruck ist ja noch leicht zu überblicken, aber wenn die WHERE-Klausel komplizierter wäre, wäre es komfortabler, wenn man die Namen der oben definierten berechneten Felder "Anfang" und "Ende" verwenden könnte, statt die Definition nochmals zu wiederholen:
SELECT Tabelle1.Bestellnummer, Aktenzeichen, Left(Bestellnummer,2) AS Anfang, Right([Aktenzeichen],2) AS Ende
FROM Tabelle1
WHERE Anfang<>Ende;
Dieser Ausdruck führt aber zu einer Fehlermeldung, schade.
Oder geht das doch irgendwie ?
Mach einfach ne Klammer (äußere Abfrage) drum und der Käse ist gegessen:
SELECT * FROM (
SELECT Tabelle1.Bestellnummer, Aktenzeichen, Left(Bestellnummer,2) AS Anfang, Right([Aktenzeichen],2) AS Ende
FROM Tabelle1
WHERE Left(Bestellnummer,2)<>Right(Aktenzeichen,2)
)WHERE Anfang = x
Ich habe hier einfach deine Abfrage in eine Klammer für eine äußere Abfrage gesetzt.
Habs nicht geprüft, sollte aber so laufen.
PS: SQL ist einfach, wenn man den Bogen mal raus hat. Lohnt sich, damit zu beschäftigen. Kannst Du dir jede Menge Arbeit sparen. Performance innerhalb SQL ist meiner Beobachtung nach deutlich (>>>) besser, als mit Formeln in VBA zu verzweigen. Außerdem entstehen dadurch unnötige Abhängigkeiten.
Gib mal n Zeichen, obs läuft
Zitat von: ebs17
Es ist regelmäßig vorteilhaft, solche Ausdrücke ... in getrennten Tabellenfeldern zu speichern ...
Ja. Manche Redundanzen sind von der Fachanwendung vorgegeben, aber ich versuche mein Bestes.
@Milvus:
Dein Beispiel hat funktioniert.
Folgende erweiterte Abfrage mit eingebetteter Subquery führt jedoch zu einem Fehler (Datentypkonflikt in Kriterienausdruck; Datenblattansicht: #Name?):
Alle Datensätze, wo der Anfang des Aktenzeichens und das Mittelstück der Bestellnummer nicht gleich sind:
Select * from
(SELECT Tabelle1.Aktenzeichen,
Left(Aktenzeichen,4) AS AZ_li,
Right(Aktenzeichen,Len(Aktenzeichen)-4) AS AZ_re,
Tabelle1.Bestellnummer,
Mid(Bestellnummer,5,Len(Aktenzeichen)-4) AS Nr_mi
FROM Tabelle1
WHERE (Tabelle1.Aktenzeichen >"")) as SQ
where SQ.AZ_re <> SQ.Nr_miDer Fehler kommt auch, wenn ich das Alias "SQ" weglasse.
Die Subquery als einfache Abfrage funktioniert dagegen tadellos !
Kann mir jemand das erklären ?
Zitat von: MilvusSQL ist einfach, wenn man den Bogen mal raus hat.
Glaube ich auch, aber die Anfangshürde ist etwas hoch. Danke an alle, die mir da drüber helfen, trotz meiner vielen Anfängerfragen.
Hmm,
Also mal Folgendes (ich kenne die Datenlage ja nicht):
Du wendest Schnippelfunktionen an.... Was liefern die, wenn sie auf Nullwerte stoßen oder auf solche, die einen kürzeren String haben,. Schätze da kommt ein Fehler raus und das kann dann die äußere Abfrage nicht vergleichen.
Schau mal in der Inneren zuerst, ob die Daten alle "gültig" für die Funktionen sind.
Lösungsansatz: Left und Right nur anwenden, wenn Strings dafür gültig sind, bzw. allgemein den Fehler abfangen. Kann man vermutlich auch nach dem Schnippeln
In Access müsste die Funktion WennFehler verfügbar sein.
SQL:
Habe eine Zeit lang mit SQL-Developer mit einer ORACLE DB gearbeitet. OK, da hat man keine grafische Oberfläche, wie in Access aber dafür ein vollständiges Debugging, in werlcher Zeile usw. welcher Fehler aufgetreten ist.
Da kann Access nicht mit!