2013-11-21 6 views
6

Ich habe 3 Tabellen mit ähnlichen Datenzeilen. Ich brauche 100 Zeilen aus allen drei Tabellen mit den folgenden Bedingungen wählen:Wie kann ich insgesamt 100 Zeilen aus 3 verschiedenen Tabellen auswählen?

nicht mehr als 25 Zeilen aus Tabelle A ausgewählt werden können -> (nennen Sie es ZÄHLWERT)

nicht mehr als 40 Zeilen aus der Tabelle B ausgewählt werden -> (count_b)

beliebige Anzahl von Zeilen aus Tabelle C (count_c), aber die Nummer sollte count_c = 100 gewählt werden - (+ ZÄHLWERT count_b)

Combine 3 tables in one collection of rows

Hier ist, was ich versucht:

SELECT * FROM 
(
    SELECT * FROM TABLE_A WHERE ROWNUM <= 25 
    UNION ALL 
    SELECT * FROM TABLE_B WHERE ROWNUM <= 40 
    UNION ALL 
    SELECT * FROM TABLE_C 
) WHERE ROWNUM <=100 

Aber die Abfrage ist zu langsam und nicht immer geben Sie mir 100 Zeilen.

+0

Ihre Abfrage sieht gut aus - in welchen Fällen gibt es nicht 100 Zeilen? –

+0

Wie Sie Ihre Bedingungen angegeben haben, sind sie zufrieden, auch wenn Sie nur die 100 Zeilen aus der Tabelle C zurückgeben. Also hier gehen Sie: SELECT * FROM TABLE_C WHERE ROWNUM <= 100 –

Antwort

2

Try WHERE ROWNUM <= 100 zur letzten Auswahl hinzuzufügen:

SELECT * FROM 
(
    SELECT TABLE_A.*, 1 as OrdRow FROM TABLE_A WHERE ROWNUM <= 25 
    UNION ALL 
    SELECT TABLE_B.*, 2 as OrdRow FROM TABLE_B WHERE ROWNUM <= 40 
    UNION ALL 
    SELECT TABLE_C.*, 3 as OrdRow FROM TABLE_C WHERE ROWNUM <= 100 
) WHERE ROWNUM <=100 
    ORDER BY OrdRow; 

Sie können auch versuchen:

SELECT * FROM TABLE_A WHERE ROWNUM <= 25 
UNION ALL 
SELECT * FROM TABLE_B WHERE ROWNUM <= 40 
UNION ALL 
SELECT * FROM TABLE_C WHERE ROWNUM <= 
     100 
     - 
     (select count(*) TABLE_A WHERE ROWNUM <= 25) 
     - 
     (select count(*) TABLE_B WHERE ROWNUM <= 40) 
+0

Das hat die Arbeit getan. und auch die Leistung ist viel besser. Danke – Ahmad

+0

Die erste Abfrage macht die unberechtigte Annahme, dass UNION ALLs das Optimierungsprogramm immer Zeilen aus der ersten Abfrage zurückgibt, gefolgt von den Zeilen aus der zweiten Abfrage usw. Sicher, das ist was Oracle in der Praxis tut, aber es ist nicht garantiert . –

+0

@ JeffreyKemp Die erste Abfrage macht keine solche Annahme. Die Reihenfolge der UNION ist hier nicht wichtig. Wir müssen 100 Zeilen aus 3 Tabellen zurückgeben, damit wir TABLE_C mit 100 Zeilen begrenzen können. In diesem Fall, selbst wenn A ansd B keine Zeilen zurückgibt, gibt C 100 zurück und wir erhalten 100 Zeilen insgesamt. – valex

0

Ja ... Ausführungsgeschwindigkeit ist ein Alptraum für jeden Entwickler oder Programmierer ... in diesem Fall können Sie wie versuchen kann ... ich denke, es wird Ihre Anfrage beschleunigen mehr

DECLARE @Table_A_Row_Count INT, @Table_B_Row_Count INT,@RemainCount INT=0 

--Getting count of primary tables 
SELECT @Table_A_Row_Count= COUNT(1) FROM TABLE_A 
SELECT @Table_B_Row_Count= COUNT(1) FROM TABLE_B 

--Calculating remaining colections 
IF @[email protected]_B_Row_Count<100 
    BEGIN 
     SET @RemainCount=100-(@[email protected]_B_Row_Count) 
    END 
ELSE 
    BEGIN 
     --You might do somthing like this if First 
     --and second table covering 100 rows 
     SET @[email protected]_A_Row_Count 
    END 

--Finaly getting 100 rows 
SELECT top @Table_A_Row_Count * FROM TABLE_A 
UNION ALL 
SELECT top @Table_B_Row_Count * FROM TABLE_B 
UNION ALL 
SELECT Top @RemainCount * FROM TABLE_C 
+1

Sehr schöner Weg> Ich mag diese Lösung. Aber ich bevorzuge das einfachste, ich habe oben akzeptiert – Ahmad

+1

@MoumitMondal Das ist SQL-Server-Syntax, nicht Oracle. –

+0

Jetzt bekomme ich es .... danke: D – Moumit

1

Versuchen wie diese,

SELECT * FROM 
(
    SELECT * FROM table_a where rownum <=25 
    UNION ALL  
    SELECT * FROM table_b WHERE ROWNUM <= 40 
    UNION ALL 
    SELECT * FROM table_c WHERE ROWNUM <= 100 - ((SELECT count(*) FROM table_a WHERE ROWNUM <= 25) + (SELECT count(*) FROM table_b WHERE ROWNUM <= 40)) 
);  
1

Technisch, würden Sie so etwas wie dieses, um zu tun haben, zu garantieren, dass Sie immer Reihen von TABLE_A und Table_B erhalten, wenn sie vorhanden sind:

SELECT * FROM (
    SELECT * FROM (
    SELECT 'A' t, TABLE_A.* FROM TABLE_A WHERE ROWNUM <= 25 
    UNION ALL 
    SELECT 'B' t, TABLE_B.* FROM TABLE_B WHERE ROWNUM <= 40 
    UNION ALL 
    SELECT 'C' t, TABLE_C.* FROM TABLE_C 
) ORDER BY t 
) WHERE ROWNUM <= 100; 

Diese ist, weil der Optimierer erlaubt ist, um die Unterabfragen in beliebiger Reihenfolge zu starten - zB parallel zu.

In Bezug auf die Leistung, ich vermute, dass die Sortierung op nicht zu viel Zeit, um die Ausführungszeit hinzuzufügen, weil es nur eine Sortierung von maximal 100 Zeilen sowieso.

Verwandte Themen