How to get records from select statement based on one column distinct value in Oracle? - oracle

Please help me with next problem:
And the result should be:
filtered by iban_code distinct

You can use row_number analytical function.
Select * from
(Select t.*,
Row_number()
over (partition by per_id, iban_code
order by main_bank_account desc) as rn
From your_table t)
Where rn=1;
Cheers!!

Related

Oracle SQL -- Finding count of rows that match date maximum in table

I am trying to use a query to return the count from rows such that the date of the rows matches the maximum date for that column in the table.
Oracle SQL: version 11.2:
The following syntax would seem to be correct (to me), and it compiles and runs. However, instead of returning JUST the count for the maximum, it returns several counts more or less like the "HAIVNG" clause wasn't there.
Select ourDate, Count(1) as OUR_COUNT
from schema1.table1
group by ourDate
HAVING ourDate = max(ourDate) ;
How can this be fixed, please?
You can use:
SELECT MAX(ourDate) AS ourDate,
COUNT(*) KEEP (DENSE_RANK LAST ORDER BY ourDate) AS ourCount
FROM schema1.table1
or:
SELECT ourDate,
COUNT(*) AS our_count
FROM (
SELECT ourDate,
RANK() OVER (ORDER BY ourDate DESC) AS rnk
FROM schema1.table1
)
WHERE rnk = 1
GROUP BY ourDate
Which, for the sample data:
CREATE TABLE table1 (ourDate) AS
SELECT SYSDATE FROM DUAL CONNECT BY LEVEL <= 5 UNION ALL
SELECT SYSDATE - 1 FROM DUAL;
Both output:
OURDATE
OUR_COUNT
2022-06-28 13:35:01
5
db<>fiddle here
I don't know if I understand what you want. Try this:
Select x.ourDate, Count(1) as OUR_COUNT
from schema1.table1 x
where x.ourDate = (select max(y.ourDate) from schema1.table1 y)
group by x.ourDate
One option is to use a subquery which fetches maximum date:
select ourdate, count(*)
from table1
where ourdate = (select max(ourdate)
from table1)
group by ourdate;
Or, a more modern approach (if your database version supports it; 11g doesn't, though):
select ourdate, count(*)
from table1
group by ourdate
order by ourdate desc
fetch first 1 rows only;
You can use this SQL query:
select MAX(ourDate),COUNT(1) as OUR_COUNT
from schema1.table1
where ourDate = (select MAX(ourDate) from schema1.table1)
group by ourDate;

Getting Error "ORA-01732: data manipulation operation not legal on this view" while deleting from a table in oracle

Same query running in Db2 , but in oracle it's giving error.
Please help. thanks in advance.
delete from (SELECT
EMP_ID,
SAL,
ROW_NUMBER() OVER (PARTITION BY EMP_ID ORDER BY SAL DESC) As RN
FROM FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1) A where RN>1}
Check documentation Notes on Updatable Views:
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database Administrator's Guide
ROW_NUMBER is an Analytic Function, so update is not permitted.
I think this one should work (not tested):
delete from FPM.FACT_PL_BS
WHERE ROWID =ANY
(SELECT ROW_ID
FROM
(SELECT ROWID as ROW_ID,
EMP_ID,
SAL,
ROW_NUMBER() OVER (PARTITION BY EMP_ID ORDER BY SAL DESC) As RN
FROM FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1)
WHERE RN > 1;
or maybe
delete from FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1
AND ROWID <>ALL
(select MAX(ROWID) KEEP (DENSE_RANK FIRST ORDER BY SAL) OVER (PARTITION BY EMP_ID)
FROM FPM.FACT_PL_BS)

Error on Partition over row number

I am creating a sub-query to select distinct entries on a certain column, DIS_COL, then return all other columns for those distinct entries, arbitrarily selecting the first row.
To do this I'm creating a sub-query that selects only first rows using over - partition by, then selecting from that sub-query.
There is an error with my code however; "ORA-00923: FROM keyword not found where expected".
My code is below:
select *
from (
select *,
row_number() over (partition by DIS_COL order by COL_2) as row_number --ORDER BY FIELD DETERMINES WHICH ROW IS THE FIRST ROW AND THUS WHICH ONE IS SELECTED.
from MY_TABLE
) as rows
where row_number = 1
AND CRITERIA_COL = 'CRIT_1'
OR CRITERIA_COL_2 = 'CRIT_2';
How can I correct my code to achieve the desired result?
I am working on an Oracle database.
Remove as rows. It is not proper syntax for the table/query alias. It is syntax for column alias.
select *
from (
select T.*,
row_number() over (partition by DIS_COL order by COL_2) as row_number --ORDER BY FIELD DETERMINES WHICH ROW IS THE FIRST ROW AND THUS WHICH ONE IS SELECTED.
from MY_TABLE t
)
where row_number = 1
AND (CRITERIA_COL = 'CRIT_1'
OR CRITERIA_COL_2 = 'CRIT_2');
It's not the ROW_NUMBER, it's the *, Add an alias to the subquery:
select *
from (
select T.*, -- here
row_number() over (partition by DIS_COL order by COL_2) as row_number --ORDER BY FIELD DETERMINES WHICH ROW IS THE FIRST ROW AND THUS WHICH ONE IS SELECTED.
from MY_TABLE
)T as rows -- and here
where row_number = 1
AND CRITERIA_COL = 'CRIT_1'
OR CRITERIA_COL_2 = 'CRIT_2';

update concat value to a single column

I want to update the concat value to a single column. Please help me to update this.
update tbl_data1
set FLD_REMARKS=
(select i.fld_id||':'||i.fld_calc_id||':'||0||':'||0
from tbl_cust_order p, tbl_cust_bill i
where i.fld_item_id=p.fld_id
and p.fld_item_id=110
and rownum =1
order by p.fld_id desc)
where fld_id=243078
You don't say what the problem is, but maybe this will help:
update tbl_data1
set FLD_REMARKS=
(select TheFld FROM (
(select i.fld_id||':'||i.fld_calc_id||':'||0||':'||0 TheFld
, ROW_NUMBER() OVER (ORDER BY p.fld_id desc) rn
from tbl_cust_order p, tbl_cust_bill i
where i.fld_item_id=p.fld_id
and p.fld_item_id=110)
WHERE rn = 1)
where fld_id=243078

Taking the record with the max date

Let's assume I extract some set of data.
i.e.
SELECT A, date
FROM table
I want just the record with the max date (for each value of A). I could write
SELECT A, col_date
FROM TABLENAME t_ext
WHERE col_date = (SELECT MAX (col_date)
FROM TABLENAME t_in
WHERE t_in.A = t_ext.A)
But my query is really long... is there a more compact way using ANALYTIC FUNCTION to do the same?
The analytic function approach would look something like
SELECT a, some_date_column
FROM (SELECT a,
some_date_column,
rank() over (partition by a order by some_date_column desc) rnk
FROM tablename)
WHERE rnk = 1
Note that depending on how you want to handle ties (or whether ties are possible in your data model), you may want to use either the ROW_NUMBER or the DENSE_RANK analytic function rather than RANK.
If date and col_date are the same columns you should simply do:
SELECT A, MAX(date) FROM t GROUP BY A
Why not use:
WITH x AS ( SELECT A, MAX(col_date) m FROM TABLENAME GROUP BY A )
SELECT t.A, t.date FROM TABLENAME t JOIN x ON x.A = t.A AND x.m = t.col_date
Otherwise:
SELECT A, FIRST_VALUE(date) KEEP(dense_rank FIRST ORDER BY col_date DESC)
FROM TABLENAME
GROUP BY A
You could also use:
SELECT t.*
FROM
TABLENAME t
JOIN
( SELECT A, MAX(col_date) AS col_date
FROM TABLENAME
GROUP BY A
) m
ON m.A = t.A
AND m.col_date = t.col_date
A is the key, max(date) is the value, we might simplify the query as below:
SELECT distinct A, max(date) over (partition by A)
FROM TABLENAME
Justin Cave answer is the best, but if you want antoher option, try this:
select A,col_date
from (select A,col_date
from tablename
order by col_date desc)
where rownum<2
Since Oracle 12C, you can fetch a specific number of rows with FETCH FIRST ROW ONLY.
In your case this implies an ORDER BY, so the performance should be considered.
SELECT A, col_date
FROM TABLENAME t_ext
ORDER BY col_date DESC NULLS LAST
FETCH FIRST 1 ROW ONLY;
The NULLS LAST is just in case you may have null values in your field.
SELECT mu_file, mudate
FROM flightdata t_ext
WHERE mudate = (SELECT MAX (mudate)
FROM flightdata where mudate < sysdate)

Resources