SQL Vergleich mit Len()

Moderator: ModerationP

SQL Vergleich mit Len()

Beitragvon ErstellerVBA » 11. Jan 2018, 14:53

Hallo Experten,

ich versuche einen Vergleich in SQL zweier Tabellen, eine ist eine Abkürzung der anderen.
Ich möchte jetzt also sehen, welche und wieviele Inhalte sich aus beiden Tabellen überschneiden.

Beispielsdaten:

Code: Alles auswählen
Tab_A
|-------------|
| ABEGAIL2536 |
| ANTWRD25    |
| ALT12866    |
|-------------|


Code: Alles auswählen

Tab_B
|-------------|
| ABEG*       |
| ANTW*D*     |
| ALT         |
|-------------|


in SQL lautet der WHERE Abschnitt bei mir so:

Code: Alles auswählen
WHERE Tab_B.Feld = Left(Tab_B.Feld, Len(Tab_A.Feld))


Ich möchte explizit Wildcard Vergleiche ausschließen, weil die Datenmengen groß sind und ich hier mit Tab_B.Feld & "*" Like Tab_A.Feld arbeiten müsste, was mein Access schon mehrfach gekillt hat.

Nur erhalte ich keine Treffer, könnt ihr mir helfen, wieso das so sein könnte?
Habe auch schon viel Zeit mit googlen verbracht, aber leider ohne Erfolg. Nur Lösungen für TSQL oder ähnlichem gefunden.

Sofern möglich, würde ich es auch gerne nativ per SQL lösen, VBA Funktionen sind hier nur eine Notlösung.

Vielen Dank im Voraus.
ErstellerVBA
 

Re: SQL Vergleich mit Len()

Beitragvon Marmeladenglas » 11. Jan 2018, 14:57

...Left(Tab_B.Feld, Len(Tab_A.Feld))

sollte das nicht genau umgekehrt sein ?
Left(Tab_A.Feld, Len(Tab_B.Feld)...
Marmeladenglas
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 16551
Registriert: 23. Jan 2008, 18:55

Re: SQL Vergleich mit Len()

Beitragvon ErstellerVBA » 11. Jan 2018, 14:59

Ja, Du hast recht. Das kommt davon, wenn man Daten anonymisiert und sich dann verzettelt. Bitte meine Dämlichkeit zu entschuldigen. :oops:
Bei meinen Daten ist es richtig herum.
ErstellerVBA
 

Re: SQL Vergleich mit Len()

Beitragvon mmarkus » 11. Jan 2018, 15:54

Also grundsätzlich kann like "abc*" einen Index nutzen, so einer vorhanden ist. Das gilt aber nicht für like "*abc*".
Bei großen Datenmengen sollte das also viel performanter als left sein, sofern die Daten indexiert sind.
Nur frage ich mich, warum du Wildecards bereits in manchen Texten hast. Das sollte nicht sein.
ms access what else
mmarkus
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 645
Registriert: 16. Apr 2012, 16:07
Wohnort: Vienna

Re: SQL Vergleich mit Len()

Beitragvon ErstellerVBA » 12. Jan 2018, 10:37

Indiziert sind beide Felder, aber ich vergleiche ca. 800 DS (Tab_B) mit 350 000 (Tab_A).

Code: Alles auswählen
Mid(Tab_A.Feld, 1, Len(Tab_B.Feld))


Liefert Ergebnisse, ich werde mal gucken, wie ich das verfeinern kann.
ErstellerVBA
 

Re: SQL Vergleich mit Len()

Beitragvon Gast » 12. Jan 2018, 10:57

weil ... ich hier mit Tab_B.Feld & "*" Like Tab_A.Feld arbeiten müsste
- versus -
eine ist eine Abkürzung der anderen

Fällt Dir selber der Widerspruch auch auf?

Code: Alles auswählen
LIKE "abc*"

Für den Teil bis zur Wildcard erfolgt eine Indexnutzung. Darauf hat mmarkus schon hingewiesen.
Eine Berechnung auf ein Tabellenfeld wie auch immer unterbindet zuverlässig die Nutzung eines Index.
Gast
 

Re: SQL Vergleich mit Len()

Beitragvon GastBiber » 12. Jan 2018, 13:25

Moin,

alles richtig, was der Gast sagt.
Unabhängig davon: wenn es in diesen Datenstrukturen doch offensichtlich so etwas wie "Oberbegriffe" oder "Gruppen" gibt, nach denen logisch zusammengefasst werden kann (nichts anderes ist doch diese TabelleB)...

-> dann sollte diese fachlich vorhandene Gegebenheit auch im Datenmodell nachgezogen werden.
Dann muss eben ein Feld "XYGruppe" ergänzt werden (also Artikelgruppe oder Auftragsgruppe oder um was auch immer es da geht), eine handelsübliche Fremdschlüsselbeziehung definiert werden und dann kann auch mit ganz normalen JOINs hantiert werden statt über ein " LIKE 'bla*'".
Das will doch wirklich keiner bei ein paar hunderttausend Datensätzen.

Grüße
Biber
Zuletzt geändert von GastBiber am 12. Jan 2018, 13:34, insgesamt 1-mal geändert.
GastBiber
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 735
Registriert: 18. Sep 2014, 18:03

Re: SQL Vergleich mit Len()

Beitragvon Gast » 12. Jan 2018, 13:29

Genau: Die LIKE-Maßnahme sollte eine einmalige sein, die Daten in normalisierte Strukturen bringt. Wer so etwas als Dauerzustand in Stammdaten verwendet, darf sich höchstens darüber beklagen, dass er nicht deswegen erschossen wird.
Gast
 

Re: SQL Vergleich mit Len()

Beitragvon ErstellerVBA » 18. Jan 2018, 11:59

Hallo zusammen,

leider verspätete Antwort dank Erkältung. Ich möchte mit diesem Schritt ja die FKs hinzufügen. Aber: diese Datenmengen (betrifft nur TabA) erhalte ich regelmäßig per Import, d.h. den Vergleich muss ich regelmäßig für alle neuen Daten durchführen (where FK is Null). Daran gibt es auch nichts zu rütteln, wird aber im Laufe der Zeit performanter.

Einmalig am Anfang betrifft es jedoch eine gigantische Menge. Und daran sitze ich gerade.

Fällt Dir selber der Widerspruch auch auf?

Für den Teil bis zur Wildcard erfolgt eine Indexnutzung. Darauf hat mmarkus schon hingewiesen.


Möglich, dass wir hier an einander vorbeireden. Ich suche eine Lösung, die bei mir a) nicht abstürzt und b) auch wirklich alle Ergebnisse liefert.
Eine Abkürzung ist es, ja, aber nicht immer eine einfache. Es sind wildcards am Anfang, zwischendurch oder am Ende möglich. D.h. ich vergleiche dann per "*" & XXXXXX & "*". Und das ist bei diesen Datenmengen absolut nicht performant.

Ich finde genug Lösungen für dieses Problem dank TSQL usw., aber das kann ich in Access dank beschränkter SQL Syntax nicht anwenden. Ich hatte jetzt gedacht, dass ich ggf. bessere Performance erhalte, wenn ich Zeichen für Zeichen vergleiche und bei nicht-match abbreche, d.h. der Vergleich von ABC zu ARD würde bei Zeichen 2 abbrechen. Aber erneut: keine Ahnung.
ErstellerVBA
 

Re: SQL Vergleich mit Len()

Beitragvon Gast » 18. Jan 2018, 12:53

Es sind wildcards am Anfang, zwischendurch oder am Ende möglich

Da waren eingangs die Versuche mit Left auch eine sackgasse und irreführend.

Den Vergleich per Mustersuche (LIKE) könnte man funtional durch die Verwendung von Instr ersetzen. Das Grundproblem (Datenmenge und keine Indexnutzung) wird dadurch aber nicht behoben, den gravierenden Performanceschub würde ich da auch nicht erwarten.

Lösung, die bei mir a) nicht abstürzt

Der "Absturz" stellt sich wie dar? Bluescreen?
Scheinbare Untätigkeit durch hohe Rechenleistung im Arbeitsspeicher ist noch kein Absturz.

Wenn die Gesamtabfrage zu langwierig ist (die man auch über eine längere Pause laufen lassen könnte), könnte man ggf. die Datenmengen teilen und nacheinander abarbeiten.
Gedanken dazu:
- Die Existenz von Duplikaten wurde noch nicht geklärt.
- Vielleicht hilft es, bei einem ersten Abgleich nur Kurz-- und Langbezeichnung in das zu verarbeitende Recordset zu nehmen und somit nicht durch an der Stelle uninteressante weitere Daten das Recordset unnötig aufzublähen. Aus den gefundenen Kombinationen könnte man vielleicht eine Zuordnungstabelle erstellen und diese dann vollindiziert einsetzen.
Gast
 

Re: SQL Vergleich mit Len()

Beitragvon mmarkus » 18. Jan 2018, 14:19

Wenn ich die Tabelle B ansehen

Code: Alles auswählen
Tab_B
|-------------|
| ABEG*       |
| ANTW*D*     |
| ALT         |
|-------------|



Dann frage ich mich, warum teilweise am Ende ein Wildcard vorhanden ist und teilweise nicht.
wenn bei ANTW*D* der Stern im String ein Wildcard ist, kann man nur mit like vergleichen. InStr kann man dann natürlich vergessen.
Instr geht nur, wenn der Stern als Text interpretiert wird.
Gemäß deinen Angaben willst du ja "*" & XXXXXX & "*" vergleichen. Das macht aber wenig Sinn wenn bereits ein Wildcard vorhanden ist. Also wie ist es nun genau??
ms access what else
mmarkus
Im Profil kannst Du frei den Rang ändern
 
Beiträge: 645
Registriert: 16. Apr 2012, 16:07
Wohnort: Vienna

Re: SQL Vergleich mit Len()

Beitragvon ErstellerVBA » 19. Jan 2018, 14:14

Hallo zusammen,

zunächst einmal vielen Dank für die tatkräftige Unterstützung.

Der "Absturz" stellt sich wie dar? Bluescreen?


Nein, Access schließt sich ohne Fehlermeldung einfach. Ich könnte dazu also nicht einmal den Fehler bestimmen.

Code: Alles auswählen
- Die Existenz von Duplikaten wurde noch nicht geklärt.


In den Daten gibt es Duplikate, die auch erwünscht sind.

Dann frage ich mich, warum teilweise am Ende ein Wildcard vorhanden ist und teilweise nicht.


Die brutale Antwort? Das ist den Usern geschuldet. Früher wurde diese Zuordnung händisch durchgeführt, da machte es keinen Unterschied, ob mit Wildcard oder ohne eingegeben. Das soll sich ändern. Ich kann die Wildcard am Ende per Update entfernen, aber ich bin mir gerade unsicher, ob es dieses Problem ändert.

Code: Alles auswählen
- Vielleicht hilft es, bei einem ersten Abgleich nur Kurz-- und Langbezeichnung in das zu verarbeitende Recordset zu nehmen und somit nicht durch an der Stelle uninteressante weitere Daten das Recordset unnötig aufzublähen. Aus den gefundenen Kombinationen könnte man vielleicht eine Zuordnungstabelle erstellen und diese dann vollindiziert einsetzen.


Das klingt interessant, hast Du hier einen Ansatz als Artikel o.ä.?
ErstellerVBA
 

Re: SQL Vergleich mit Len()

Beitragvon Gast » 19. Jan 2018, 17:39

Ansatz?
Maßnahmen leite ich von Daten ab. Datensatzzahlen hattest Du ja schon genannt. interessant wäre ein repräsentativer Querschnitt der üblichen Daten, ergänzt durch die (zu erwartenden) Problemfälle, die ja auch durch die Routine mit abgedeckt werden sollen.
Bei Identifikation per Instr / Mustersuche muss man es für möglich halten, dass Kurzbezeichnungen sich mehrfach wie kombiniert in Langbezeichnungen wiederfinden können, sofern das nicht sachlich oder per Definition ausgeschlossen ist.
Ja, und integrierte Wildcards in Stammdaten sind sehr verwirrend. Auf so etwas kommt man nicht zwingend durch eigenes Verständnis, das muss explizit erklärt werden. "Beliebige" Useraktionen in Abweichung von erwarteten Standards dann auch.

Eine weitere Frage wäre es, ob die Lang- sowie Kurzbezeichnungen in sich konstant und eindeutig sind oder zusätzliche Variationen auftreten können.
Gast
 

Re: SQL Vergleich mit Len()

Beitragvon Gast » 19. Jan 2018, 21:16

Nach einem Entspannungsbad (hilft beim Beruhigen und Ordnen von Gedankenakrobatik) würde ich folgendes ergänzen wollen:
Tab:B: ANTW*D*

Wenn die Sternchen als Wildcard zu verstehen sind und so eingesetzt werden, dann hääte die Mustersuche so ein Aussehen:
Code: Alles auswählen
WHERE Langbezeichnung LIKE '*' & 'ANTW*D*' & '*'

Das Sternchen steht für beliebige Zeichen in Anzahll von 0 bis beliebig. Im Ergebnis hätte man am Beispiel eine UND-Verknüpfung von (vermutlich) drei Mustersuchen, also eine Verdreifachung des Tablescan aus dem CROSS JOIN der beiden großen Tabellen. Da mag man sagen: Geschickt ist das nicht.

Außerdem: Wenn die Kurzbezeichnung schon zwei Wildcards beinhaltet, gibt es da mehrere atomare Informationen außerhalb der Wildcards. Im Sinne der 1. NF könnte man also Feldinhalte zerlegen und nach etwas Zwischenarbeit atomare Inhalte indexunterstützt auf Gleichheit testen.
Gast
 


Zurück zu Access Forum (provisorisch)

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 6 Gäste