Reputation: 77
Schema:
Table A: AID(PK), RECEIVE_DATE
Table B: BID(PK), AID(FK), MESSAGE, ITEMID, ITEMTYPE
Tables A-to-B have a one-to-many mapping.
Here is a working SQL query (in SQL Server) to find out the latest message grouped by ITEMID i.e for different ITEMID (of ITEMTYPE say as 'XYZ').
SELECT
b.MESSAGE, b.ITEMID
from a
inner join b on b.aid = a.aid AND b.ITEMTYPE = 'XYZ'
where a.receive_date in (select max(receive_date)
from a a1
inner join b b1 on b1.aid = a1.aid
where b1.itemid = b.itemid
);
How can we rewrite this SQL query without IN
clause [also without rownumber concept in use], as ORACLE is having restriction for IN clause. Getting java.sql.SQLSyntaxErrorException: ORA-01795: maximum number of expressions in a list is 1000 for above expression.
Upvotes: 1
Views: 2470
Reputation: 4820
EXISTS
and IN
tend to be interchangeable, and EXISTS
performs better in some engines (not sure about Oracle) due to the fact that it returns true on the first match, rather than generating a subset and checking against that. I'm not familiar with Oracle, but I imagine you could use the following to circumvent your 1000 row limit on IN
:
SELECT
b.MESSAGE, b.ITEMID
from a
inner join b on b.aid = a.aid AND b.ITEMTYPE = 'XYZ'
where exists (
SELECT 1
from a a1
inner join b b1 on b1.aid = a1.aid
where b1.itemid = b.itemid
having MAX(a1.receive_date) = a.receive_date
)
Upvotes: 2
Reputation: 520998
It isn't clear to me why you are getting ORA-01795
. Your subquery only selects a max value, which should be a single value. In addition, the 1000 value limit only applies to a list of literals, not a subquery. In any case, you could rephrase this query using a join instead of WHERE IN
:
SELECT
b.MESSAGE,
b.ITEMID
FROM a
INNER JOIN b
ON b.aid = a.aid AND b.ITEMTYPE = 'XYZ'
INNER JOIN
(
SELECT
b1.itemid,
MAX(receive_date) AS max_receive_date
FROM a a1
INNER JOIN b b1
ON b1.aid = a1.aid
GROUP BY b1.itemid
) t
ON b.itemid = t.itemid
WHERE a.receive_date = t.max_receive_date
Upvotes: 3