PDA

View Full Version : SQL set oder select into mit dynamischer Selektion



Seiten : 1 2 3 [4]

BenderD
02-10-25, 12:59
... mein Denkfehler bezüglich Vergleiche mit NULL war, dass "is null" der einzige Vergleich ist, der true liefern kann. Ansonsten ist das Resultat immer false - womit man natürlich rumspielen kann. Wie auch immer: die between Variante mit coalesce für die Felder, die null werden könnten ist einfacher und lesbarer.

Fuerchau
02-10-25, 15:58
Aber nicht unbedingt performanter, da das Feld auf jeden Fall abgefragt werden muss.
Frage ich zuerst den Parameter auf leer ab, wird der Or-Zweig nicht geprüft.
Wenn die Prüfung dann u.U. auch noch auf einen left Join geht, kann der Optimierer ggf. sogar auf den Zugriff verzichten.
Aber mit der Performance ist das so eine Sache.
Ich habe eine komplexe Preisfindung sqltechnisch optimert und somit vereinfacht (z.B. mit join lateral). Da der Zugriff aber keine Massendaten verarbeitet dauerte die alte Preisfindung ca. 100 Millissekunden und die neue liegt bei kleiner 5. Das wird dann erst bei einer Preisliste auffallen, wenn 10.000de Preise abgefragt werden.

Fuerchau
09-10-25, 12:13
Final lässt sich noch folgendes sagen:
Ein count(*) vorher und anschließend enen normalen Select ist auch kontraproduktiv, da man 2x die Datenbank abfragen muss. Der count(*) dauert durchaus genauso lange wie der 2. SQL.

Mittels

select count(*) over() as Anzahl
, F.*
from MyFile F
where ....

erhält man beim 1. Fetch bereits die Anzahl Zeilen. Zusätzlich bleibt diese Anzahl dann auch stabil im Ergebnis. Für das befüllen kann man dann z.B. die ersten 2000 Zeilen laden.
Ein where "x between min and max" führt zu einem Tablescan und auch nicht zu einer Indexnutzung.

Und was die ganze Diskussion angeht und 0 oder Blank zulässige Bedingungen sind, so hilft auch hier der Null-Anzeiger:

where ( : P1 : Ind1 is null or Col1 = : P1)
and ( : P2 : Ind2 is null or Col2 = : P2)
usw.

Wenn laut obiger Aussage P1 und P2 beliebige Werte haben können aber ingnoriert werden sollen, so wird die Bedingung eben wahr, wenn Ind1 = -1 ist und somit P1 als NULL angenommen wird und P1 is null somit true ist.
Die Anzahl der Kombinationen ist mit den Nullanzeigern beliebig kombinierbar.

BenderD
09-10-25, 12:37
- in einer Anzeige gibt es keine null values, die müssen eh mit coalesce raus!
- von der Performance macht man für sowas einen Blockfetch, der sagt einem auch gleich noch, wieviele es gelesen hat. Bei Maximalgröße zeigt man dann > 1000, wenn man denn in einen 1000er Block einliest. Dann stimmt der Wert auch und eine angezeigte Auswahlliste ist immer eh nur eine Momentaufnahme.

ILEMax
09-10-25, 14:38
@Baldur Irgendwas fehlt mir ...

Subfile mit


PLZ Vertreter NR

1 v1 n1
1 v11 n3
1 v12 n1
2 v21 n1
2 v22 n24
3 v11 n1



Im CTRLSATZ kann ich filter setzen

Wenn ich PLZ auf 3 setze soll ein Satz kommen (ind2 und ind3 auf -1 setzen)
Wenn ich Vertreter auf v11 setze sollen 2 Sätze kommen (ind1 und ind3 auf -1 setzen)
Wenn ich Vertreter auf v11 setze und Nr auf n3 soll ein Satz kommen (ind1 auf -1 setzen)

Die variablen im CTRL-Satz heissen PLZ, VT und NR
Die variablen in der Datei heisseb D_PLZ, D_VT und D_NR

SQL für die 3 selektionen sieht so aus?


select count(*) over () as anzahl, D_plz, d_vt, d_nr
from datei
where (:Plz :ind1 is null or :plz = d_plz)
and (:VT :ind2 is null or :VT = D_VT)
and (:NR :ind3 is null or :NR = D_NR)


Und wenn es 87.524 Sätze sind, die die gewählte kombination haben, steht das in (allen) gefetchten Sätzen in Anzahl?
Richtig?

Fuerchau
09-10-25, 17:09
Ja, bei den sog. OLAP-Funktionen wird dies für jeden Satz ausgeworfen.
Dies hat den Vorteil, dass man auch Summenergebnisse verrechnen kann.
Z.B:

Menge * 100 / nullif(sum(Menge) over(), 0) AnteilMenge
Menge * 100 / nullif(sum(Menge) over(Partition by Auftrag), 0) "AnteilMenge je Auftrag"

u.v.m.

Der Vorteil des Count beim Subfile-Laden ist, man könnte dem User nach dem 1. Fetch die Zahl nennen und anbieten die ersten 2000 Zeilen zu laden ohne noch mal neu abfragen zu müssen.