我有3个包含相似数据行的表。 我需要从以下三个表中选择100行:
从表A中可以选择不超过25行 - > (将其命名为count_a)
从表B中可以选择不超过40行 - > (count_b)
可以从表C(count_c)中选择任意数量的行,但数字应该是 count_c = 100 - (count_a + count_b)
以下是我的尝试:
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行。
答案 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