如何从3个不同的表中共同选择100行?

时间:2013-11-21 07:23:28

标签: sql oracle

我有3个包含相似数据行的表。 我需要从以下三个表中选择100行:

从表A中可以选择不超过25行 - > (将其命名为count_a)

从表B​​中可以选择不超过40行 - > (count_b)

可以从表C(count_c)中选择任意数量的行,但数字应该是    count_c = 100 - (count_a + count_b)

Combine 3 tables in one collection of rows

以下是我的尝试:

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

但是查询太慢了,并不总是给我100行。

4 个答案:

答案 0 :(得分:2)

尝试将WHERE ROWNUM <= 100添加到最后一个选择:

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;

你也可以尝试:

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)

答案 1 :(得分:1)

试试这个,

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))
);     

答案 2 :(得分:1)

从技术上讲,你必须做这样的事情,以保证你总是从TABLE_A和TABLE_B中获取行(如果它们存在):

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;

这是因为优化器允许以其喜欢的任何顺序运行子查询 - 例如并行。

关于性能,我怀疑排序操作不会给执行时间增加太多时间,因为它最多只能排序100行。

答案 3 :(得分:0)

是的......执行速度对每个开发人员或程序员来说都是一场噩梦...... 在这种情况下,您可以尝试......我认为它会加快您的查询速度

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 @Table_A_Row_Count+@Table_B_Row_Count<100 
    BEGIN
        SET @RemainCount=100-(@Table_A_Row_Count+@Table_B_Row_Count)
    END
ELSE
    BEGIN
        --You might do somthing like this if First
        --and second table covering 100 rows
        SET @Table_B_Row_Count=100-@Table_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