How to get rows from a table if total rows are more than 10 in Oracle? - sql

I want to write a Oracle based query where I can choose if I want to see the results. Let's say:
SELECT *
FROM table
//when there are more than 10 rows
How can I do this?

select * from table
where 10 < (select count(*) from table)

Best speed:
select * from table
where 10=(select count(*) from
table
where rownum <11)
:)
UPDATE: Because there are suspicions that I claim something that is not true, here some tests:
In SQL Developer(keep in mind that select * from table will offer only first 50 rows, but count(*) read all requested rows)
The table has no indexes.
select
count(*) from
table
22074412 rows
3.16 seconds
select * from table where 10 =
(select
count(*) from
table
where rownum <11
)
0.051 seconds
select * from table where 10 <
(select
count(*) from
table
)
3.39 seconds
select count(*) from table where 10 <
(select
count(*) from
table
)
7.69 seconds
select count(*) from table where 10 =
(select
count(*) from
table
where rownum <11
)
3.42 seconds
Cause: Subquery with rownum is faster (it reads not the entire table)

DECLARE #Var int;
SET #Var = SELECT COUNT(*) FROM [somewhere]
IF #Var > 10
BEGIN
SELECT * FROM [somewhere]
END
You mean something like that?
Or just how to use the where clause?
SELECT *
FROM [somewhere]
WHERE (SELECT COUNT(*) FROM [somewhere]) > 10

This should do it for you:
SELECT * FROM [table] WHERE (SELECT COUNT(1) FROM [table]) > 10

select * from YourTable where (select count(*) from YourTable ) > 10

if you would like to avoid double scans and you have valid statistics you can
select * from table a, all_tables b
where b.num_rows > 10
and b.table_name = 'table';

Related

Odd requirement of SQL Query

I have a table with columns 'Id' and 'Status'.
I want to write a SQL statement to select top 50 rows from this table with 25 rows with Status 1 and 25 rows with Status 2 in one SQL query.
I want my result to have rows with alternate status.
Please suggest me how to write this Query.
If you use MSSQL you can do this:
SELECT TOP 25
*
FROM
Table1
WHERE
Table1.Status=1
UNION ALL
SELECT TOP 25
*
FROM
Table1
WHERE
Table1.Status=2
If you use MYSQL you have to use LIMIT. Like this:
(
SELECT
*
FROM
Table1
WHERE
Table1.Status=1
LIMIT 25
)
UNION ALL
(
SELECT
*
FROM
Table1
WHERE
Table1.Status=2
LIMIT 25
);
For SQL Server, use TOP:
SELECT TOP 25 * FROM TableName WHERE Status=1
UNION ALL
SELECT TOP 25 * FROM TableName WHERE Status=2
For alternative result:
SELECT * FROM
(
SELECT TOP 25 *,ROW_NUMBER() OVER(ORDER BY Status) as RN FROM TableName WHERE Status=1
UNION ALL
SELECT TOP 25 *,ROW_NUMBER() OVER(ORDER BY Status) as RN FROM TableName WHERE Status=2
) T
ORDER BY RN

SQL - Insert if the number of rows is greater than

I have created a SQL query that will return rows from an Oracle linked server. The query works fine and will return 40 rows, for example. I would like the results to only be inserted into a table if the number of rows returned is greater than 40.
My thinking would then be that I could create a trigger to fire out an email to say the number has been breached.
DECLARE #cnt INT
SELECT #cnt = COUNT(*) FROM LinkedServer.database.schemaname.tablename
IF #cnt > 40
INSERT INTO table1 VALUES(col1, col2, col3 .....)
Let's say that the query is:
select a.*
from remote_table a
Now you can modify the query:
select a.*, count(*) over () as cnt
from remote_table a
and will contain the number of rows.
Next,
select *
from (
select a.*, count(*) over () as cnt
from remote_table a
)
where cnt > 40;
will return only if the number of rows is greater than 40.
All you have to do is
insert into your_table
select columns
from (
select columns, count(*) over () as cnt
from remote_table a
)
where cnt > 40;
and will insert only if you have more than 40 rows in the source.
Create Procedure in sqlserver and use count() function for conditional checking for row count or use ##ROWCOUNT.
if ((select count(*) from Oraclelinkservertable) > 40)
begin
-- code for inserting in your table
Insert into tablename
select * from Oraclelinkservertable
end
Try using OFFSET.
SELECT * FROM tableName ORDER BY colName OFFSET 40 ROWS

How can I collectively select 100 rows from 3 different tables?

I have 3 tables containing similar rows of data.
I need to select 100 rows from all of the three tables with the following conditions:
No more than 25 rows can be selected from Table A --> (name it count_a)
No more than 40 rows can be selected from Table B --> (count_b)
Any number of rows can be selected from Table C (count_c) but the number should be
count_c = 100 - (count_a + count_b)
Here is what I tried:
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
But the query is too slow and does not always give me 100 rows.
Try to add WHERE ROWNUM <= 100 to the last select:
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;
Also you can try:
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)
Try like this,
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))
);
Technically, you'd have to do something like this in order to guarantee that you'll always get rows from TABLE_A and TABLE_B if they exist:
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;
This is because the optimizer is allowed to run the subqueries in any order it likes - e.g. in parallel.
With regard to performance, I suspect that the sort op will not add too much time to the execution time because it's only sorting a maximum of 100 rows anyway.
Yes ... Execution speed is a nightmare to every developer or programmer ...
In that case you can try like ... i think it will speed up your query more
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

How to select top records from a table not using TOP / ROWNUM?

There is TOP command. However, if we want not to use the TOP command what would be the best way of selecting top 5 records?
SELECT TOP 5 * FROM table1;
A simple but very inefficient approach:
select * from
(select t.*,
(select count(*)
from table1 c
where c.order_column <= t.order_column) top_n
from table1 t) sq
where top_n <= 5

How to select a record if the query returns one row, or select no record if the query returns more rows?

I require to select a row if there is only one row exists, if there are more rows, it should select 0 rows.
If you're using PL/SQL, then selecting the column using select-into will throw a too_many_rows exception if there's more than one row returned:
declare
var table.column%type;
begin
select column
into var
from table
where ...;
end;
If you want to do this just using SQL, then you can do something like:
select *
from
(select s.*, count(*) over () c
from
(select *
from table
where ...
and rownum <= 2
) s
)
where c = 1
UPDATE
As DazzaL says in the comments, the reason for the rownum <= 2 restriction is to short-circuit the query if there's more than 2 rows in the result set. This can give significant performance benefits if the dataset is large.
I came up with this, just for the heck of it, using a CTE
With counter as
( select count(any_field) as cnt from your_query
)
SELECT
your_query
WHERE exists (SELECT cnt from Counter WHERE cnt=1)
1 row when there's 1 record - http://sqlfiddle.com/#!4/84c7b/2
0 rows when more than 1 rec - http://sqlfiddle.com/#!4/95c4a/1
EDIT
or if you want to avoid repeating the whole query... an example :
(using the schema from sqlfiddle http://sqlfiddle.com/#!4/6a2d8/117 )
With results as
( select * from montly_sales_totals
),
counter as
( SELECT count(name) as cnt FROM results
)
SELECT *
FROM results
WHERE exists (SELECT cnt from Counter WHERE cnt=5)
SELECT fld1, fld2
FROM (SELECT COUNT(*) over() cnt ,fld1, fld2 FROM tbl WHERE fld1 = 'key')
WHERE cnt = 1
I require to select a row if there is only one row exists, if there
are more rows, it should select 0 rows.
I assume the table contains only the row(s) you are interested to see (or not to see), in that case I would write something like
select *
from table1
where 1 = (select count(1)
from table1
)
In case you want to see only one row from a subset of results from your table, I would go for something like:
with t as ( select *
from table1
where [put here your condition]
)
select *
from t
where 1 = (select count(1)
from t
)
Try this:
SELECT f1,f2
FROM Table
WHERE (f1 = #f1) AND (f2=#f2) AND (f3=#f3)
GROUP BY f1,f2
HAVING (COUNT(*) = 1)
DECLARE COL_COUNT NUMBER;
BEGIN
COL_COUNT: = 0 ;
SELECT COUNT (1) INTO COL_COUNT FROM USER_TAB_COLUMNS WHERE TABLE_NAME = '(ur table name)';
IF COL_COUNT = 0 THEN
EXECUTE IMMEDIATE ('select * from dual') ;
END IF;
END;
Try this:
SELECT col1, col2 FROM
(SELECT count(id) as 'cnt', col1, col2 FROM table_name WHERE col1='value')
WHERE cnt=1;