oracle query to display the similar value rows at last..? - oracle

I need to display the similar values rows of the table at last while the remaining rows of the table has to come in ascending order...
for ex:
Name salary
---------------------
a 100
b 200
c 300
c 400
c 600
d 200
e 500
I need the output as ,
Name salary
-----------------------
a 100
b 200
d 200
e 500-----------------till here it has to come in ascending order ignoring 'c'
c 300
c 400
c 600

You can use the below query and modify it accordingly
select name,salary,(select count(name) from table_name where name=a.name) count_nm from table_name a order by count_nm,salary;
Hope this helps!

Related

Oracle | Retrieval of records from tables having One to many relationship

I have two tables which share one-to-many relationship. MY_FACT is the parent table whereas MY_RMDETAILS is the child table having multiple records for a single parent record.
Table MY_FACT:
FACT_ID
FACT_DATE
TOTAL_DEMAND
1000
21/04/2022
500
2000
21/04/2022
500
Table MY_RMDETAILS:
RM_ID
FACT_ID
PROMISE_QTY
REQUEST_QTY
RM_ITEM_NAME
200
1000
500
500
RM1
201
1000
400
500
RM2
202
1000
500
500
RM3
203
1000
400
500
RM4
300
2000
500
500
RM1
301
2000
500
500
RM2
302
2000
500
500
RM3
303
2000
500
500
RM4
I need to write a query to have below output.
Logic:
If MY_RMDETAILS.PROMISE_QTY is less than MY_RMDETAILS.REQUEST_QTY, the supply is insufficient.
So for any given MY_FACT record, if any one of its children records from MY_RMDETAILS has PROMISE_QTY less than REQUEST_QTY, the flag SUPPLY_SUFFICIENT in output should be N else it should be Y.
And INSUFFICIENT_RMs column in output should show the MY_RMDETAILS.RM_ITEM_NAME of "insufficient" records as comma separated format.
EXPECTED OUTPUT:
FACT_ID
FACT_DATE
TOTAL_DEMAND
SUPPLY_SUFFICIENT?
INSUFFICIENT_RMs
1000
21/04/2022
500
N
RM2,RM4
2000
21/04/2022
500
Y
Please help. Thanks in advance.
You can try to use subquery with condition aggregate function.
SELECT t2.*,
CASE WHEN t1.INSUFFICIENT_cnt > 0 THEN 'N' ELSE 'Y' END,
t1.INSUFFICIENT_RMs
FROM (
SELECT FACT_ID,
LISTAGG(CASE WHEN PROMISE_QTY < REQUEST_QTY THEN RM_ITEM_NAME END, ', ') WITHIN GROUP (ORDER BY RM_ID) INSUFFICIENT_RMs,
COUNT(CASE WHEN PROMISE_QTY < REQUEST_QTY THEN RM_ITEM_NAME END) INSUFFICIENT_cnt
FROM MY_RMDETAILS
GROUP BY FACT_ID
) t1 INNER JOIN MY_FACT t2
ON t1.FACT_ID = t2.FACT_ID

PLSQL procedure to populate qty based on previous record values

I have a following table
- ITEM_NUMBER QTY_FROM QTY_TO
- ABC 10
- ABC 20
- ABC 30
- DEF 100
- DEF 250
- DEF 400
I need to write a plsql procedure which will populate QTY_to column based on qty_from next row for same item number.
for example if item number is ABC and qty_from is 10 on first row and 20 on next row....id expect the procedure to look at second row...and populate qty_from on the first one as 19 (next_row_qty_from - 1).
select ITEM_NUMBER, QTY_FROM,
lead(QTY_FROM, 1) over (partition by ITEM_NUMBER, order by QTY_FROM) - 1 as QTY_TO
from table;
As a third parameter to lead function you can add default value. This will be used when no next row exist for given ITEM_NUMBER so in case of row - ABC 30 if you do lead(QTY_FROM, 1, QTY_FROM) there will be 29 as QTY_TO but you haven;t defined edge case in your question.
No procedure needed, just simple update:
update t
set qty_to =
(select min(qty_from)-1 from t t2
where item_number = t.item_number and qty_from > t.qty_from)
Result:
SQL> select * from t order by item_number, qty_from;
ITEM_NUMBER QTY_FROM QTY_TO
----------- -------- -------
ABC 10 19
ABC 20 29
ABC 30
DEF 100 249
DEF 250 399
DEF 400
6 rows selected

How to select two max value from different records that has same ID for every records in table

i have problem with this case, i have log table that has many same ID with diferent condition. i want to select two max condition from this. i've tried but it just show one record only, not every record in table.
Here's my records table:
order_id seq status____________________
1256 2 4
1256 1 2
1257 0 2
1257 3 1
Here my code:
WITH t AS(
SELECT x.order_id
,MAX(y.seq) AS seq2
,MAX(y.extern_order_status) AS status
FROM t_order_demand x
JOIN t_order_log y
ON x.order_id = y.order_id
where x.order_id like '%12%'
GROUP BY x.order_id)
SELECT *
FROM t
WHERE (t.seq2 || t.status) IN (SELECT MAX(tt.seq2 || tt.status) FROM t tt);
this query works, but sometime it gave wrong value or just show some records, not every records.
i want the result is like this:
order_id seq2 status____________________
1256 2 4
1257 3 2
I think you just want an aggregation:
select d.order_id, max(l.seq2) as seq2, max(l.status) as status
from t_order_demand d join
t_order_log l
on d.order_id = l.order_id
where d.order_id like '%12%'
group by d.order_id;
I'm not sure what your final where clause is supposed to do, but it appears to do unnecessary filtering, compared to what you want.

How to Get Count of the Particular records in Oracle?

I am taking various status from a employee table which has 230 records with below 5 status.
I have written query for taking the count for each and every status but now need combined count of Status A and B as AB.
My Query:
SELECT DISTINCT Status AS Status,
COUNT(Status ) AS StatusCount
FROM EMPLOYEE
GROUP BY Status
My Query Output is:
Status Count
A 100
B 50
C 30
D 10
E 40
I want result as A&B Combined and remaining as same.
Status Count
A&B 150
C 30
D 10
E 40
Use a case
SELECT case when Status in ('A','B')
then 'A&B'
else Status
end AS Status,
COUNT(Status) AS StatusCount
FROM EMPLOYEE
GROUP BY case when Status in ('A','B')
then 'A&B'
else Status
end
Use can use decode also
SELECT decode(status,'A','A&B','B','A&B',status) AS Status,
COUNT(status) AS StatusCount
FROM EMPLOYEE
GROUP BY decode(status,'A','A&B','B','A&B',status) AS Status

Can I limit results using IN and COUNT?

I need to limit the results from a query, but I can't implement any example I've seen using count and rownum. Given this table
rec error
___ _____
1 123
2 123
3 456
4 456
5 456
6 456
7 456
8 456
9 456
10 789
11 789
12 789
13 789
This table has many more rows with many different error codes. I'm using this to get the records i need:
select rec, error from table where error in (123,456,789)
But say I want to only return no more than 2 records per error. I'm not sure how to do this. If I was only looking for a single error, I could simply use count or rownum. Not sure how to do it when using the IN condition.
Do you care which two rows you get for any particular error code? Something like this will get you the two rows for each error code with the smallest rec value. If you change the ORDER BY in the ROW_NUMBER analytic function, you can change which two rows are returned.
SELECT rec,
error
FROM (SELECT rec,
error,
row_number() over (partition by error
order by rec asc) rnk
FROM your_table_name)
WHERE error in (123,456,789)
AND rnk <= 2

Resources