[T-SQL]Zufällige Datensätze

ag3nt

Lieutenant
Registriert
Okt. 2002
Beiträge
689
Hallo,
ich habe da ein kleines Problem beim dem ich hoffe, dass mir ein paar SQL-Profis
weiterhelfen können.
Ich habe eine etwas umfangreichere SQL-Abfrage die derzeit aus knapp 15 UNION's
besteht (Tendenz steigend) und die selektierten Daten in eine Tabelle anfügt.

Nun sollen aus dieser Tabelle ein bestimmter Prozentsatz an zufälligen Datensätzen
entnommen werden. Der Prozentsatz richtet sich dabei entweder nach der Gruppierung
"mainid" oder ("mainid", "subid") und steht in einer zweiten Tabelle.

Lauffähig sein soll das ganze auf dem MS-SQL-Server2000.

Ich habe mir zwar schon mal etwas überlegt, allerdings finde ich diesen Ansatz zu komplex
und wollte mal fragen ob jemand eine bessere Idee hat die etwas weniger aufwendig ist.
Code:
--Das Feld "subid" wird mit Hilfe eines Insert-Triggers berechnet,
--während "mainid" direkt angegeben wird
INSERT INTO 
    #table_with_inserttrigger( mainid, ... )
	
    SELECT ...
    FROM   TABLE_1
    WHERE  ...
UNION
    ...
UNION
    SELECT ...
    FROM   TABLE_n
    WHERE  ...
;
GO


SELECT 
    IDENTITY(INT, 1, 1) AS OrderID
    SubSelect.*
INTO
    #ordered_table
FROM (
    SELECT TOP 100 PERCENT
    ,   C.percent AS perc
    ,   CASE C.usesubid WHEN 1 
            THEN T.subid 
            ELSE 0 
          END AS virtualid
    ,   ...
    FROM
        #table_with_inserttrigger T
        INNER JOIN
            counted C
        ON	C.mainid = T.mainid

    ORDER BY 
        p.listenid
    ,   virtualid
    ,   NEWID()
) AS SubSelect;
GO


SELECT 
    ...
FROM 	 
    #ordered_table M
    INNER JOIN (
        SELECT
            mainid
        ,   virtualid
        ,   MIN( IDENTITYCOL ) AS min
        ,   MIN( IDENTITYCOL ) + ( COUNT( IDENTITYCOL ) - 1 ) * perc AS max
        FROM
            #ordered_table
        GROUP BY
            perc
        ,   mainid
        ,   subid
      ) AS Range
    ON    Range.mainid = M.mainid
    AND   Range.virtualid  = M.virtualid

WHERE 	 
    M.OrderID BETWEEN Range.min AND Range.max
;

edit: hab den Quellcode so abgeändert, dass der Select auch so funktioniert wie er soll, allerdings wird dadurch der Aufwand noch gesteigert
 
Zuletzt bearbeitet:
aus was für einem progi greifst du auf die datenbank zu?
kann du das resultat der abfrage nicht in einen array speichern und dann die daten mit einem loop über den array selektionieren?
 
Mit einem Program selbst wird nicht gearbeitet, sondern das Problem ist ein kleiner Ausschnitt aus einer StoredProcedure. Einzige Möglichkeit wären demnach Cursor, die bringen hier aber fast nur Nachteile in der Geschwindigkeit. Laufzeitmäßig liegt das Problem vorallem beim Sortieren das circa 75% der Zeit beansprucht. Was ich suche ist vor allem eine Alternative die ohne die Durchnummerierung der Zeilen auskommt. Trivial ist es nicht aber vielleicht fällt ja doch jemandem etwas ein.
 
Zurück
Oben