SQL statistische Abfragen

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von heinkurz.

    SQL statistische Abfragen

    Hi!

    2 knifflige Fragen:

    1)

    Ich habe in einem Datenbankfeld eine Codierung für Fotos mit 0 bis 5 Buchstaben, z.B. "IK", "MBK", "B", "CI", etc. Nun hätte ich gerne in einem einzigen Query eine Statistik wie oft kommt "I" vor, wie oft kommt "B" vor, etc. für jeden Buchstaben.

    2)

    In einem anderen Feld habe ich Codes für die Motive mit 3 Zahlen mit 1. Zahl = Übergruppe, 2. Zahl = Gruppe, 3. Zahl = Motiv, z.B. 653 = Fauna / Insekten / Libellen. Eine Statistik wie oft kommt 653 vor ist ja kein Problem aber könnte man auch mit einem Query ausgeben: 6?? kommt w mal vor, 65? kommt x mal vor, 653 kommt y mal vor, 654 kommt z mal vor, etc. Also aufsteigend von Übergruppe zu Gruppe und Motiv und das in einem Query?

    Danke

    VB1963 schrieb:

    Ansätze:
    zu 1) schaue nach dem LIKE-Operator und verwende ihn im WHERE-Abschnitt...
    zu 2) versuche es mit Cint(Code/100) = 6 und Cint(Code/10) = 65 als Vergleich im WHERE-Abschnitt...

    ad 1) Dann müsste ich aber jeden Buchstaben einzeln abfragen, ich hätte es aber gern in einem einzigen Query.

    ad 2) Da es ein Stringfeld ist könnte ich es auch mit SUBSTR machen aber ... siehe ad 1)
    VB1963 hat dir schon richtigen Ansätze gegeben. Mit UNION kannst du das auch in einer Query lösen.
    Deine Probleme stellen sich aber eigentlich nur wegen dem (schlechten?) Datenbankdesign... aber gut:

    zu 1)
    Du könntest dir z.B. per distinct, count und group by alle holen und dann Programmseitig entsprechend die Statistik aufbauen. Was je nach Datenlage kurz dauern kann (Worst Case = 26^5 Iterationen, wenn du 26 Kategorien etc. hast).
    Per SQL fällt mir nur so etwas (hässliches) ein:

    SQL-Abfrage

    1. SELECT 'A' AS x, COUNT(*) AS y FROM t WHERE c LIKE '%A%'
    2. UNION
    3. SELECT 'B' AS x, COUNT(*) AS y FROM t WHERE c LIKE '%B%'
    4. UNION
    5. ...
    6. UNION
    7. SELECT 'Z' AS x, COUNT(*) AS y FROM t WHERE c LIKE '%Z%'

    Das ganze kann man natürlich mit einer Schleife zusammenbauen oder auch 26 Einzelabfragen (mit Prepare-Statement) machen oder falls du gerade noch eine Tabelle mit den Buchstaben hast, kannst du die natürlich auch dranjoinen und dir den String für like zusammenkonkatenieren. Je nach DBMS kann man das evtl. auch besser bzw. kürzer machen, z.B. mit VALUES in der FROM-Klausel.

    zu 2)
    Würdest du ein Integer-Feld statt String nehmen, wäre die Lösung halbwegs schick... aber so, naja:

    SQL-Abfrage

    1. SELECT CONCAT(STR(INT(INT(c)/100)), '??') AS x, COUNT(*) AS y FROM t GROUP BY INT(INT(c)/100)
    2. UNION
    3. SELECT CONCAT(STR(INT(INT(c)/10)), '?') AS x, COUNT(*) AS y FROM t GROUP BY INT(INT(c)/10)
    4. UNION
    5. SELECT c AS x, COUNT(*) AS y FROM t GROUP BY c

    (CONCAT, STR und INT durch entsprechende Funktionen deiner DB ersetzen)
    Ok, im Grunde hat sich das Problem nun erledigt. Ich hab die Datenbank reorganisiert und komprimiert und nun laufen die Queries wieder in vernünftigen Zeiten von Nullkommairgendwas Sekunden ab, sodass ich auch mehrere Abfragen laufen lassen kann.

    Danke für eure Hilfe.