简体   繁体   中英

How to retrieve half of records from a table - Oracle 11g

How can i retrieve (select) half of records from a table, for example, a table with 1000 rows, retrieve 500 (50%) from the table. (in this case i can use rownum because we know the exact quantity of rows (1000) - select * from table where rownum <= 500 ), but i have to count every table to achieve the statement.

What's the best way do you think i can do this?

Well, you could count the rows and select half:

select *
from   my_table
where  rownum <= (select count(*)/2 from my_table)

That would tend to select rows that are contiguous within the physical segments.

Or ...

select *
from   (select rownum rn, * from my_table)
where  mod(rn,2) = 0

That would tend to select "every other" row, so you'd get a pretty even spread from the physical data segments.

Or ...

select *
from   my_table sample (50)

That would be approximately half of the rows.

Or ...

select *
from   my_table sample block (50)

That would be the rows from approximately half of the data blocks below the high water marks of the segments.

Probably lots of different ways available, and which one you want probably depends on whether you want the selected pseudo-randomly or not.

If you want to use the output of the query, use something like:

select ...
from   (select *
        from   my_table
        where  rownum <= (select count(*)/2 from my_table)) my_table
join   ...

In that circumstance the SAMPLE syntax would be more compact.

With NTILE window function:

select * from (SELECT *, NTILE(2) OVER(ORDER BY (SELECT NULL FROM DUAL)) nt FROM TableName) as t
where nt = 1

or:

select * from (SELECT *, NTILE(2) OVER(ORDER BY NULL) nt FROM TableName) as t
where nt = 1

If you are on Oracle 12c , you could use the Top-n row limiting feature which allows to limit by percentage of rows .

For example, in my EMP table in SCOTT schema I have 14 rows , and I want first 50 percent rows based on order by sal:

SQL> SELECT empno, sal FROM emp
  2  ORDER BY sal
  3  FETCH FIRST 50 PERCENT ROWS ONLY;

     EMPNO        SAL
---------- ----------
      7369        800
      7900        950
      7876       1100
      7521       1250
      7654       1250
      7934       1300
      7844       1500

7 rows selected.

SQL>

As far my knowledge goes, the best way to perform this operation is by executing the following block of code:

SELECT * FROM table_name
WHERE ROWNUM <= (SELECT COUNT(*)/2 FROM table_name);

And to get the second half:

SELECT * FROM
(SELECT ROWNUM AS RN,table_name.* FROM table_name)
WHERE RN > (SELECT COUNT(*)/2 FROM table_name);

which half of the rows do you want ?

this gets every other row...

Select * from table t
Where Mod(rownum, 2) = 0

this gets first half ...

Select * from table t
Where rownum <= 
    (Select count(*) 
     from table) / 2

If total no of records are not even number, above query won't work, here is the working query regardless of count(*)/2 returns either whole number or decimal

SELECT ROWNUM, tmp.* 
FROM employees tmp
WHERE TO_NUMBER(ROWNUM) <= (SELECT count(*)/2 FROM employees);

here it is another query to retrive the first half of your table:

SELECT * FROM your_table LIMIT (SELECT COUNT(*)/2 FROM your_table);

Also you have this option for retrive the second half of the same table:

SELECT * FROM your_table OFFSET (SELECT COUNT(*)/2 FROM your_table);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM