subquery returning row in HQL - oracle

I want to do following:
INSERT INTO Table0(value1, value2)
SELECT
(SELECT t1.something1 FROM Table1 t1 WHERE t1.id = :t1id),
(SELECT max(t2.something2) FROM Table2 t2 WHERE t2.some = :t2Some)
FROM Table1, Table2
But hibernate complains that I want to insert entity (Table1) as string (value1). It looks like subqueries in HQL returns entities instead of column values. Can I force it not to do so?
I know, that I can do like:
INSERT INTO Table0(value1, value2)
SELECT t1.something1, max(t2.something2) FROM Table1 t1, Table2 t2 WHERE ...
but it generates bad SQL for Oracle, because there is HIBERNATE_SEQUENCE.NEXTVAL in SELECT and Oracle does not allow to do so.

It looks like first query works now, maybe it was about Hibernate version.

Related

getting error- ORA-00905: missing keyword

Select * from table1 t1 left outer join table2 t2 on t1.id=t2.id and
case
when t1.id in (select t2.id from table2)
then t1.valid_to_ts > sysdate and t2.valid_to_ts>sysdate
else
t1.valid_to_ts>sysdate.
getting error-
ORA-00905: missing keyword
You can use UNIONs to implement the logic of the case:
SELECT *
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.id IS NULL
AND t1.valid_to_ts > SYSDATE
UNION ALL
SELECT *
FROM table1 t1 LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t1.id IS NOT NULL
AND t1.valid_to_ts > SYSDATE
AND t2.valid_to_ts > SYSDATE;
As Álvaro González said in a comment, you can't use a case expression as a flow control operator. You can use a case expression in a where or on clause, but only by making it generate a value which you then compare with something else, which can be awkward, so it's usually better not to. You can usually replace the logic you're trying to implement with simple Boolean logic.
In this case you're already joining to table2 so your subquery isn't needed; you can use a where clause to see if a matching record was found - preferably checking for a not-null column other than ID, so this example will only work if valid_to_ts is not nullable:
select * from table1 t1
left outer join table2 t2
on t1.id = t2.id
where t1.valid_to_ts > sysdate
and (t2.valid_to_ts is null or t2.valid_to_ts > sysdate)
If t2.valid_to_ts is nullable then you should use a different not-nullable column instead; unless you want to include values with no valid-to date - but you aren't doing that for t1.valid_to_ts.
If you try to check that in the on clause then you won't filter out IDs which do exist in table2 but with an earlier date.
db<>fiddle, including an on-clause version which gets the wrong result (as far as I can tell from your starting query anyway).
For the demo I've assumed that the _ts columns are dates, since you're comparing with sysdate; if they are actually timestamps (as the suffix might suggest) then you could compare with systimestamp instead.

Workaround for delete in hive with join conditions

So i'm trying to convert a SQL delete query to Hive one. Im using hive .12 version's which doesn't supports delete.
Below is the SQL query:
Delete from t1 c where exists(select 1 from t2 a where
a.emplid=c.employee_id and a.project_status='test')
Now i tried tried using NOT IN for the above query but due to some reasons we cannot use NOT IN in our queries.
below is Hive query i have written but i'm not sure as its not giving correct results. i'm pretty new to hive. can anyone help on this.
INSERT Overwrite table t1
select * from t1 c left outer join t2 a on (c.employee_id=a.employee_id)
where a.project_status= 'test'
and a.employee_id is null
Move project_status='test' condition to the subquery or into the on clause. Also you should select columns only from table c.
Example with filter in the subquery:
insert overwrite table t1
select c.*
from t1 c
left join (select employee_id
from t2
where project_status='test'
) a on (c.employee_id=a.employee_id)
where a.employee_id is null;
Example with additional condition in the ON:
insert overwrite table t1
select c.*
from t1 c
left join t2 a on (c.employee_id=a.employee_id and a.project_status='test')
where a.employee_id is null;

Hive :Insert the records that are not present

I need to insert records into a table t1 from another table t2 such that insert only the records that are not in t2.
But when i use this query
insert into table t1 select * from t2 where id not in (select id from t1);
But I get error as
Correlating expression cannot contain qualified column reference.
Can anybody suggest me a query to do this.
t2.id
Yet another ridiculous hive limitation
insert into table t1 select * from t2 where t2.id not in (select id from t1);
You can also use below command :-
insert into table t1 select t2.* from t2 left join t1 on t2.id=t1.id where t1.id is NULL;

Convert rownum from Oracle in Postgres, in "having" clause

I need to convert a query from Oracle SQL to Postgres.
select count(*) from table1 group by column1 having max(rownum) = 4
If I replace "rownum" with "row_number() over()", I have an error message: "window functions are not allowed in HAVING".
Could you help me to get the same result in Postgres, as in Oracle?
The query below will do what your Oracle query is doing.
select count(*) from
(select column1, row_number() over () as x from table1) as t
group by column1 having max(t.x) = 6;
However
Neither oracle not postgres will guarantee the order in which records are read unless you specify an order by clause. So running the query multiple times is going to be inconsistent depending on how the database decides to process the query. Certainly in postgres any updates will change the underlying row order.
In the example below I've got an extra column of seq which is used to provide a consistent sort.
CREATE TABLE table1 (column1 int, seq int);
insert into table1 values (0,1),(0,2),(0,3),(1,4),(0,5),(1,6);
And a revised query which forces the order to be consistent:
select count(*) from
(select column1, row_number() over (order by seq) as x from table1) as t
group by column1 having max(t.x) = 6;

Converting rownum from Oracle to Postgres

I need to make a conversion from Oracle SQL to PostgreSQL.
select * from table1 inner join table2 on table1.id = table2.table1Id
where table1.col1 = 'TEST'
and rownum <=5
order by table2.col1
If I delete and rownum <=5 and put at the end limit 5, there are differences between the 2 dialects. In Oracle, first are selected the 5 elements, and after that, they are sorted by table2.col1 . In Postgres, first all the list is sorted, and AFTER there are selected the first 5 elements.
How can I obtain the same result in Postgres as in Oracle?
Thanks!
To get the behavior you desire, you can use a subquery like this:
SELECT * FROM (
SELECT table1.col1 as t1col1, table2.col1 as t2col1
FROM table1 INNER JOIN table2 ON table1.id = table2.table1Id
WHERE table1.col1 = 'TEST'
LIMIT 5
) AS sub
ORDER BY t2col1;
I named the columns there because in your example both tables had a col1.
Note however that without any ordering on the inner query, the selection of 5 rows you get will be purely random and subject to change.
Depending on the version you are using, PostgreSQL 8.4 and above have Window functions. Window function ROW_NUMBER() is capable of implementing the functionality of Oracle pseudo column rownum.
select row_number() over() as rownum,* from table1 inner join table2 on table1.id = table2.table1Id where table1.col1 = 'TEST' and rownum <=5 order by table2.col1;

Resources