MS-Office-Forum
Google
   

Zurück   MS-Office-Forum > Microsoft Access & Datenbanken > Microsoft Access - Code Archiv
Registrieren Forum Hilfe Alle Foren als gelesen markieren

Banner und Co.

Antworten
Ads Der Renner, 11 Entwicklertools für Access, Tipps & Trick und offene Datenbanken zum einzigartigen Preis.
Themen-Optionen Ansicht
Alt 08.10.2017, 19:49   #1
ebs17
MOF Guru
MOF Guru
Standard Grundlagen - SQL ist leicht (10) - Nummerierung in Abfragen

Desweilen wünscht man sich eine fortlaufende Datensatznummerierung analog der Zeilennummerierung in Excel. Zum einen dient es der schönen deutschen Ordnung, an der sich das Auge weiden kann, wenn alles sauber durchnummeriert ist. Zum anderen braucht man solche Durchnummerierungen wirklich, u.a.
- weil man in Kreuztabellenabfragen Aufzählungsfelder als Spaltenüberschrift erzeugen will,
- weil man gezielt auf bestimmte Datensätze nach Reihenfolgekriterien zugreifen oder solche Datensätze auch verknüpfen könnte (z.B. jeden fünften Datensatz, den vierten folgenden Arbeitstag auf ein Datum usw.),
- weil man überhaupt erst so etwas wie eine ID in einer Menge von gleichen Datensätzen erzeugen will.

Die Lösungen in "Laufende Nummer" (FAQ 3.11) können die genannten Aufgaben teilweise erledigen und werden hier in Gegenüberstellung gezeigt. Die hier vorgestellte Lösung , die aus einer Funktion in Zusammenarbeit mit zwei globalen Variablen besteht, kann zusätzlich auch durchnummerieren, wenn es kein (verwendbares) Feld zur Unterscheidung gibt. Hier wird nach der vorgenommenen Sortierung nummeriert.

Einschub: Die Bestimmung einer laufenden Nummer per Unterabfrage bzw. DCount im SELECT-Teil der Abfrage hat ein systematisches Problem. In einer Datenbanktabelle sowie -abfrage gibt es keine nutzbare Reihenfolge, wo man einen Zähler einfach hochzählen könnte (in einem Recordset mit dieser Tabelle/Abfrage dann schon). Daher zählt man bei diesen beiden Varianten über alles nach einem Kriterium, und das pro Datensatz der Hauptabfrage. Das bedeutet, mit steigenden Datensatzzahlen wird der jeweilige Vergleichen-Zählen-Aufwand größer, und natürlich erfordern mehr Datensätze auch mehr Zählungen. Damit steigt die benötigte Laufzeit überproportional zur Datensatzzahl-Steigerung bis hin zur praktischen Unverwendbarkeit. Die Domänenaggregatfunktion (Methode des Accessobjektes, nicht Methode der VBA-Bibliothek) scheint in dieser Verwendung der Datenbankmaschine etwas Intelligenteres zu übergeben im Vergleich zu dem, wie die Datenbankmaschine das pure SQL abarbeitet.
Die hier vorgestellte Lösung QueryIncrement hat dieses systematische Problem nicht.
Code:

' mod_QueryIncrement

Public gQI_Category As String
Public gQI_Icount As Long

Public Function QueryIncrement(ByVal Init As Variant, _
                               ByVal StartValue As Long, _
                               ParamArray Categories() As Variant) As Long
    Dim k As Long, v As Variant
    Dim sAllCategories As String

    v = Init
    If IsMissing(Categories) Then
        sAllCategories = "$$$$$"
    Else
        For k = 0 To UBound(Categories)
            If IsNull(Categories(k)) Then Categories(k) = vbNullString
        Next
        sAllCategories = Join(Categories, "|")
    End If

    If gQI_Category = sAllCategories Then
        gQI_Icount = gQI_Icount + 1
    Else
        gQI_Category = sAllCategories
        gQI_Icount = StartValue
    End If
    QueryIncrement = gQI_Icount
End Function
Syntaxgegenüberstellung der Varianten für eine gleiche Aufgabe:
Code:

SELECT 
   T.A, 
   T.C, 
   T.Betrag, 
   QueryIncrement(T.A, 1, T.A, T.C) AS LfdNr 
FROM 
   tblDaten AS T 
ORDER BY 
   T.A, 
   T.C, 
   T.Betrag 

'--------------------------------------------------------------------

SELECT 
   T.A, 
   T.C, 
   T.Betrag, 
   (
      SELECT 
         COUNT(*) 
      FROM 
         tblDaten AS X 
      WHERE 
         X.A = T.A 
            AND 
         X.C = T.C 
            AND 
         X.Betrag < T.Betrag 
   ) 
   + 1 AS LfdNr 
FROM 
   tblDaten AS T 
ORDER BY 
   T.A, 
   T.C, 
   T.Betrag 

'--------------------------------------------------------------------

SELECT 
   T.A, 
   T.C, 
   T.Betrag, 
   DCount('*', 'tblDaten', 'A = ' & T.A & ' AND C = ''' & T.C & ''' AND Betrag < ' & T.Betrag) + 1 AS LfdNr 
FROM 
   tblDaten AS T 
ORDER BY 
   T.A, 
   T.C, 
   T.Betrag
Es wird auffallen, dass die Syntax zur Verwendung von QueryIncrement nicht so hohe Hürden aufbaut wie z.B. die DCount-Variante.
Zusätzlich wurde eine Performancebetrachtung durchgeführt (im angehängten Bild sichtbar, in der angehängten Demo nachvollziehbar). Dort wurde mit sortierten und gemischten Daten sowie mit verschiedenen Indizierungen variiert.

Zum Abschluss zwei Anmerkungen:
1) Bei der Lösung QueryIncrement wird strikt durchgezählt, die Vergabe eines gleichen Ranges bei gleicher Punktzahl ist nicht möglich. Auch das ist in den vorhandenen Abfragen nachvollziehbar.
2) Es liegt in der Natur von globalen Variablen, dass diese ihren Wert behalten, wenn kein unbehandelter Fehler auftritt. Wenn also eine Abfrage mit QueryIncrement zum zweiten Mal aufgerufen wird und dabei die erstverwendete Kategorienliste des Neuabrufes mit der letztverwendeten und gespeicherten Kategorienliste übereinstimmt, würde die Zählung fortgeführt statt neu begonnen. In einem solchen Fall müsste man die Variablen vorher resetten.
Angehängte Grafiken
Dateityp: png testergebnis.png (25,4 KB, 10x aufgerufen)
Angehängte Dateien
Dateityp: zip NummerierungInAbfragen.zip (43,5 KB, 5x aufgerufen)

__________________

Ein freundliches Glück Auf!

Eberhard

Abfrageperformance ist kein Geheimnis
SQL ist leicht: {0}:{1}:{2}:{3}:{4}:{5}:{6}:{7}:{8}:{9}:{10}
Dein Dankeschön: DBWiki=>Spende

Geändert von ebs17 (08.10.2017 um 20:01 Uhr).
ebs17 ist offline  
verlinken auf Del.icio.us Diese Seite zu Mister Wong hinzufügen
Antworten Auf Beitrag antworten
Ads
Antworten


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Besucher: 1)
 
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge anzufügen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

vB Code ist An.
Smileys sind An.
[IMG] Code ist An.
HTML-Code ist An.
Gehe zu


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:49 Uhr.


Partner und Co.
Access-Paradies -Alles rund um die Datenbank Microsoft Access -Code -Programme-Tools -Tipps   Kostenlose Tipps & Tricks, Downloads und Programme   www.kulpa-online.com - Tipps - Tricks - Tutorials - Meinungen - Downloads uvm...   vb@rchiv · Willkommen in der Welt der VB Programmierung   Access-Garhammer - Hier finden Sie jede Menge Beispiel-Datenbanken zu Access und mehr ...   mcseboard.de   Die Top Seite für Excel-VBA-Makros uvm.

Powered by: vBulletin Version 3.6.2 (Deutsch)
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.

Copyright ©2000-2010 MS-Office-Forum. Alle Rechte vorbehalten.
Copyright ©Design: Manuela Kulpa ©Rechte: Günther Kramer
Eine Verwendung der Inhalte in anderen Publikationen, auch auszugsweise,
ist ohne ausdrückliche Zustimmung der Autoren nicht gestattet.
Beachten Sie bitte auch unsere Nutzungsbedingungen.