How to get minimum unused number from a column in Oracle and Linq? - oracle

I have a column named voucher_number. The data in this column looks like
1, 2
I want a query (in oracle and linq as well) to return 0,3,4,5,6,7,8,9,10
Note: i am taking range (0 to 10 )as a parameter parameter from screen(aspx page)

You can use MINUS operator as following:
Select voucher_num from
(
(Select level - 1 as voucher_num from dual
Connect by level <= 11)
Minus
(Select voucher_number from your_table)
)
Order by voucher_num;
Cheers!!

Related

How to split a comma-separated value to columns using connect by

I have a column with less than <50 comma separated values. And the number of comma separated values in that particular column is not constant I would like to query this table with IN/AND/OR clause for these comma separated values:
So I would like to:
split these values into separate columns in the select query
Query for a person's market code with AND, OR and IN :
EUP and APCAC
APAC or EU Or CA
IN ( APAC,EU,LATIM)
I have to use this query in spring data jpa native query
I don't want to use as many substr.
I thought to accomplish this by using connect by with level would be useful after referring the following answers - ans1 and ans2
Usertable:
username
market_code
in_use
john
eup,apac,Latim
0
sebastin
apac,Latim
0
xavier
ca,apac,Latim
0
However the following only returns one row where I expected to have 3 rows :
select regexp_substr(market_code,'[^|]+', 1, level) from testautomadm.userpool
where AND USERNAME = 'john'
connect by regexp_substr('market_code', '[^|]+', 1, level)
is not null
Any help to solve this use case much appreciated.
Thank you!
You can use the multiset and hierarchy query as follows:
Select user_name,
listagg(market_code, ',') within group (order by pos) as market_code,
In_use
From
(Select user_name,
regexp_substr(market_code, '[^,]+',1, column_value) as market_code,
in_use,
column_value as pos
From t,
table(cast(multiset(
select level from dual
connect by level <= length (regexp_replace(t.market_code, '[^,]+')) + 1
) as sys.OdciNumberList)) levels) t
Where market_code in ('EUP','APCAC')
Group by user_name, in_use
Having count(distinct market_code) = 2
Above query shows the usage of AND as we have used count = 2 You can use count = 1 and respective market_code in IN for OR And IN query

Trying to display top 3 amount from a table using sql query in oracle 11g..column is of varchar type

Am trying to list top 3 records from atable based on some amount stored in a column FTE_TMUSD which is of varchar datatype
below is the query i tried
SELECT *FROM
(
SELECT * FROM FSE_TM_ENTRY
ORDER BY FTE_TMUSD desc
)
WHERE rownum <= 3
ORDER BY FTE_TMUSD DESC ;
o/p i got
972,9680,963 -->FTE_TMUSD values which are not displayed in desc
I am expecting an o/p which will display the top 3 records of values
That should work; inline view is ordered by FTE_TMUSD in descending order, and you're selecting values from it.
What looks suspicious are values you specified as the result. It appears that FTE_TMUSD's datatype is VARCHAR2 (ah, yes - it is, you said so). It means that values are sorted as strings, not numbers - and it seems that you expect numbers. So, apply TO_NUMBER to that column. Note that it'll fail if column contains anything but numbers (for example, if there's a value 972C).
Also, an alternative to your query might be use of analytic functions, such as row_number:
with temp as
(select f.*,
row_number() over (order by to_number(f.fte_tmusd) desc) rn
from fse_tm_entry f
)
select *
from temp
where rn <= 3;

Loop through date range

How to loop Oracle query through the date? I have to put variable in 4 place. My query start with WITH AS, so I can't use Oracle SQL Loop through Date Range solution.
I also can't create temporary table.
Here is my attempt:
WITH d
AS (
SELECT DATE'2015-06-22' + LEVEL - 1 AS current_d
FROM dual
CONNECT BY DATE'2015-06-22' + LEVEL - 1 < DATE'2015-10-04'
),
OrderReserve
AS (
SELECT cvwarehouseid
,lproductid
,SUM(lqty) lqty
FROM ABBICS.iOrdPrdQtyDate
GROUP BY cvwarehouseid
,lproductid
)
SELECT
...
WHERE IORDREFILL.DNCONFIRMEDDELDATE < CAST(TO_CHAR(d.current_d , 'YYYYMMDD') AS NUMBER(38))
...
If I understand you correctly, you assume that you can only use 1 inline table per query. That is not true, you can use multiple inline tables and expand the existing WITH clause with another to loop through dates:
with OrderReserve as (
SELECT cvwarehouseid
,lproductid
,SUM(lqty) lqty
FROM ABBICS.iOrdPrdQtyDate
GROUP BY cvwarehouseid
,lproductid
), date_range as (
select sysdate+level
from dual
connect by level <= 30
)
select *
from OrderReserve, date_range
... -- expand with date_range as you see fit
;

Oracle pagination ROWNUM column>=value challenge

Having some trouble with oracle pagination. Case:
Table with > 1 billion rows:
Measurement(Id Number, Classification VARCHAR, Value NUMBER)
Index:
ON Measurement(Value)
I need a query that gets the first match and the following 2000 matches ordered by Value. I also would like to use the index.
First idea:
SELECT * FROM Measurement WHERE Value >= 1234567890
AND ROWNUM <= 2000 ORDER BY Value ASC
Result:
The query just returns the first 2000 cases it can find in the table, starting from the top, where Value is higher or equal to 1234567890, and then orders that resultset ascending.
Second idea:
SELECT * FROM
(SELECT * FROM Measurement WHERE Value >= 1234567890 ORDER BY Value ASC)
WHERE ROWNUM <= 2000
Result:
Oracle does not understand that ROWNUM should limit the amount from the inner query, so oracle decides to get all rows where Value is greater or equal to 1234567890 first, and then order that giant resultset before returning the first 2000 rows. Because Oracle is guessing that most of the data in the table will be returned, it ignores any use of index as well.
None of these approaches are acceptable as the first one gives the wrong results, and the second one takes hours.
Is pagination supported at all in Oracle?
You can use the following
SELECT * FROM
(SELECT Id, Classification, Value, ROWNUM Rank FROM Measurement WHERE Value >= 1234567890)
WHERE Rank <= 2000
order by Rank
You do not need to order in the sub-query. Simply unnecessary.
The above is not pagination but the firs page I would suppose.
Not sure if you got the solution for your problem, but to put my two cents:
The first query will not answer your requirements as it will fetch 2000 random records that satisfy your query and then do an order by.
Coming to the second query :
Oracle will first do the execution of the second query and will then only move to the outer query. So, the rownum filter will be applied only after the inner query is executed.
You can try the below approach, to do INDEX FAST FULL SCAN, i have tested it on a table with 2.76 million rows and it is having lesser cost than the other approach:
SELECT * from Measurement
where value in ( SELECT VALUE FROM
(SELECT Value FROM Measurement
WHERE Value >= 1234567890 ORDER BY Value ASC)
WHERE ROWNUM <= 2000)
Hope it Helps
Vishad
I think I have fond a potential solution. However, it's not a query.
declare
cursor c is
SELECT * FROM Measurement WHERE Value >= 1234567890 ORDER BY Value ASC;
l_rec c%rowtype;
begin
open c;
for i in 1 .. 2000
loop
fetch c into l_rec;
exit when c%notfound;
end loop;
close c;
end;
/
Kindly experiment with more options
SELECT *
FROM( SELECT /*+ FIRST_ROWS(2000) */
Id,
Classification,
Value,
ROW_NUMBER() OVER (ORDER BY Value) AS rn
FROM Measurement
where Value > 1234567889
)
WHERE rn <=2000;
Update1:- Force the use of index on Value.Here IDX_ON_VALUE is the Name of the index on Value in Measurement
SELECT * FROM
(SELECT /*+ INDEX(a IDX_ON_VALUE) */* FROM Measurement
a WHERE value >=1234567890 )
ORDER BY a.Value ASC)
WHERE ROWNUM <= 2000

Trying to create a "List of Values " including a table value and numbers below it

So basically say I have a table called "Device" and then one of the columns is "Quantity," what if I wanted to create a list of values that takes that number, say the quantity is 4, and the values are (quantity - 1) until !> 0, so in this case (4, 3, 2, 1)
I am using Oracle APEX and am assuming I need a dynamic LOV based on a sql query, but not sure how to get this. I've never used a for loop with PL/SQL
Thanks
You don't need loops for this.
select level
from dual
connect by level <= 4
order by level desc;
This should do it. Make sure that where I've put /* xxx */ you include a where clause that comes up with only 1 record. Most likely, you will use the ID of the Device table here.
SELECT ROWNUM display_value
, ROWNUM return_value
FROM DUAL
CONNECT BY ROWNUM <= (SELECT Quantity FROM Device WHERE /* xxx */)
ORDER BY ROWNUM DESC;

Resources