Oracle equivalent of Postgres' DISTINCT ON?
The same effect can be replicated in Oracle either by using the first_value()
function or by using one of the rank()
or row_number()
functions.
Both variants also work in Postgres.
first_value()
select distinct col1,
first_value(col2) over (partition by col1 order by col2 asc)
from tmp
first_value
gives the first value for the partition, but repeats it for each row, so it is necessary to use it in combination with distinct
to get a single row for each partition.
row_number()
/ rank()
select col1, col2 from (
select col1, col2,
row_number() over (partition by col1 order by col2 asc) as rownumber
from tmp
) foo
where rownumber = 1
Replacing row_number()
with rank()
in this example yields the same result.
A feature of this variant is that it can be used to fetch the first N rows for a given partition (e.g. "last 3 updated") simply by changing rownumber = 1
to rownumber <= N
.
SELECT DISTINCT OVER TEXT as needs over common query in PostgreSQL and Oracle
Oracle doesn't support DISTINCT
with CLOB
column. You can use TO_CHAR
(when the maximum length of CLOB column is less than 4000
)
SELECT DISTINCT to_char(description) from FOLDER;
Since you mentioned in comment that it is working fine for oracle, I assume there is no length issues. As you are looking for common solution for both POSTGRES
and ORACLE
, I would propose CAST
SELECT DISTINCT CAST(description as varchar(3000)) from FOLDER;
This should work in both databases.Change the VARCHAR(N)
accordingly upto the maximum limit.
CAUTION : I won't recommend using VARCHAR
instead of VARCHAR2
in oracle.
The VARCHAR datatype is synonymous with the VARCHAR2 datatype. To avoid possible changes in behavior, always use the VARCHAR2 datatype to store variable-length character strings.
How do I (or can I) SELECT DISTINCT on multiple columns?
SELECT DISTINCT a,b,c FROM t
is roughly equivalent to:
SELECT a,b,c FROM t GROUP BY a,b,c
It's a good idea to get used to the GROUP BY syntax, as it's more powerful.
For your query, I'd do it like this:
UPDATE sales
SET status='ACTIVE'
WHERE id IN
(
SELECT id
FROM sales S
INNER JOIN
(
SELECT saleprice, saledate
FROM sales
GROUP BY saleprice, saledate
HAVING COUNT(*) = 1
) T
ON S.saleprice=T.saleprice AND s.saledate=T.saledate
)
using select distinct with multiple columns but all columns musnt be distinct
Postgresql supports the DISTINCT ON syntax: http://www.postgresql.org/docs/current/interactive/sql-select.html
select distinct on (a.personalId, a.fileId) a.personalId, a.fileId, a.name, a.surname, a.address
from my_table a
See Oracle equivalent of Postgres' DISTINCT ON? for how to do this in Oracle.
How to use multiple distinct on statements in Postgres while retaining the correct order
I'd add dump_date DESC
to the ORDER
SELECT DISTINCT ON (time, forecast)
*
FROM t
ORDER BY time, forecast, dump_date DESC
How to implement Oracle count(distinct) over partition in Postgres
Postgres doesn't support count(distinct)
directly. But you can implement it with a subquery:
select . . .,
sum( (seqnum_tm = 1)::int) as mob_segments_count ,
sum( (seqnum_tr = 1)::int) as countries_count
from (select . . .,
row_number() over (partition by pm.trans_id, pm.country_reg_region_cd order by pm.country_reg_region_cd) as seqnum_tr,
row_number() over (partition by pm.trans_id, pm.mobseg_state order by pm.pm.mobseg_state) as seqnum_tm
. . .
) . . .
The idea is simple. Calculate row_number()
on the partition by
keys and the distinct column. Then, just add up the number of times when the value is "1". This requires a subquery, because you cannot nest window functions.
SELECT DISTINCT, ORDER BY expressions must appear in select list - error when migrating from Oracle to Postgres
Your query works in Postgres 13 and later. If you start a new project, then you should use the most recent version, rather than starting with a slightly outdated version
In older versions, you can wrap it in a derived table to get around that.
select *
from (
SELECT DISTINCT *
FROM TABLE_A A
JOIN TABLE_B B ON A.BIC = B.BIC
WHERE B.CUST_NUMBER=?
AND A.LOCATION=?
AND B.STATUS=?
AND B.LIVE=TRUE
) a
ORDER BY A.TYPE, A.PARTY
Postgres 12 example
Postgres 14 example
Postgres: Why DISTINCT ON expression(s) must match the leftmost ORDER BY expression(s)?
Well, the ORDER BY is needed to keep those rows together that share the same value for the "distinct columns". The database processes them sequentially discarding all subsequent rows from the same set. If the rows weren't sorted, this wouldn't be easily possible.
Assume this set of rows:
c1 | c2
---+----
1 | 100
2 | 10
1 | 200
2 | 15
If you want the c1 to be unique and pick the highest c2 you would need to use
select distinct on (c1) *
from the_table
order by c1, c2 desc;
The order by
itself will generate the following result:
c1 | c2
---+----
1 | 200
1 | 100
2 | 15
2 | 10
By processing that result row-by-row the database can now efficiently discard every but the first row for each c1
value by simply checking if that value changes from row to another. If the result wasn't sorted this check would be become far more complicated.
Related Topics
How to Include Null Values in a Min or Max
Dynamic SQL to Generate Column Names
Left Join Turns into Inner Join
Using Pivot on Multiple Columns of an Oracle Row
Execute Immediate Within a Stored Procedure Keeps Giving Insufficient Priviliges Error
SQL Query to Find Nth Highest Salary from a Salary Table
Ms SQL "On Delete Cascade" Multiple Foreign Keys Pointing to the Same Table
How Much Disk-Space Is Needed to Store a Null Value Using Postgresql Db
SQL Query Distinct with Row_Number
Seeing the Underlying SQL in the Spring Jdbctemplate
Create Trigger to Log SQL That Affected Table
Combining the Results of Two SQL Queries as Separate Columns