using MAX function in HQL - hql

The below query has some issues. The subquery that I use here runs without any errors when run separately. However if I run the whole query below it ends in error.
"Error while compiling statement: FAILED: ParseException line 13:30 cannot recognize input near 'select' 'max' '(' in expression specification"
select acct_num from table1
where ind = 'Y'
and b = (select max(yr_mth_num) from table2)
and st_dt = (select cast(max(st_dt) as date) from table2)

Try this:
SELECT T1.acct_num
FROM table1 T1
LEFT SEMI JOIN
(SELECT
max(yr_mth_num) as max_yr_mth_num,
cast(max(st_dt) as date) as max_st_dt
FROM table2) T2
ON T1.b = T2.max_yr_mth_num
AND T1.st_dt = T2.max_st_dt
AND T1.ind = 'Y'

Related

Update statement with concat & inner join on Oracle

I'm trying to create an update query that concatenates 3 fields from a table to 1 field in another table
The first table called table1
ID DESC
12 left:Middle:Right
The second table Table 2
ID FLD1 FLD2 FLD3
12 left Middle Right
Trying to update all the desc field on Table1 with the values of table2 where table1.id = table2.id
update table1 A SET A.DESC = (SELECT CONCAT(B.fld1, ':', B.fld2, ':', B.fld3)
from table2 B
where A.ID = B.ID)
Where A.id = 12;
However, I'm getting an error from the above query saying "invalid number of arguments" Any idea what am I doing wrong? or how can I get this done in a better way?
CONCAT accepts only two parameters, which means that you have to use nested CONCATs.
Though, you'd rather use the double pipe || operator which doesn't have such a restriction. So:
update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3 --> this
from table2 B
where A.ID = B.ID)
Where A.id = 12;
To update all matching rows, you could
update table1 A SET A.DESC = (SELECT B.fld1 ||':'|| B.fld2 ||':'|| B.fld3 --> this
from table2 B
where A.ID = B.ID)
Where exists (select null
from table2 b
where a.id = b.id);
or MERGE:
merge into table1 a
using table2 b
on (b.id = a.id)
when matched then update set a.desc = b.fld1 ||':'|| b.fld2 ||':'|| b.fld3;
As you got duplicates, DISTINCT might help, e.g.
update table1 a set
a.desc = (select distinct b.fld1 ||':'|| b.fld2 ||':'|| b.fld3
from table2 b
where a.id = b.id
)
where exists ...
If not, then you'll have to see what to do with these duplicates. If possible, use yet another column(s) in WHERE clause. Or, if you don't really care which concatenated combination fits, use aggregate function(s) such as MIN or MAX, e.g.
update table1 a set
a.desc = (select max(b.fld1 ||':'|| b.fld2 ||':'|| b.fld3)
from table2 b
where a.id = b.id
)
where exists ...

OR in Select Oracle

select * from table1 t1 where t1.column1 = 'someValue' and ((t1.column2 =1) OR (sysdate < select t1.DateColumn2 + t2.DateColumn2/1440
from
table2 t2 where t1.column3 = t2.column3));
if t1.column2 =1 evaluates to false, I want to check another condition if time t1.DateColumn2 + t2.DateColumn2 is < sysdate . Oracle is throwing syntax error near or condition. Cant sysdate be used directly like that? Not sure where I am going wrong. Thanks
If I am guessing your intention correctly, you want an exists clause
select *
from table1 t1
where t1.column1 = 'someValue'
and ( (t1.column2 =1)
OR exists( select 1
from table2 t2
where t2.column3 = t1.column3
and sysdate < t1.DateColumn2 + t2.DateColumn2/1440 ));
Or just join the two tables in the outer query assuming there is at most 1 row in t2 per t1 row (if there is exactly 1 row you should do an inner join rather than a left outer join)
select t1.*
from table1 t1
left outer join table2 t2
on( t1.column3 = t2.column3 )
where t1.column2 = 1
or sysdate < t1.DateColumn2 + t2.DateColumn2/1440;

ORA-00904 invalid identifier for nested select

I have been stuck on this error for 2 hours.
I have nested select to get the first value.
select tbl.table_name,
(select distinct(FirstItem)
from
(select first_value(column_name) over (order by timestamp asc rows unbounded predecing) as FirstItem
from log_table_b l
where tbl.assignment_no = l.rpt_no)
) as "USERNAME",
from prod_table tbl;
It returns this error:
ERROR at line 6:
ORA-00904: "TBL"."ASSIGNMENT_NO": invalid identifier
I have tried many things, none of them seems to be helping me.
You can't use the parent table in inner sub query. Here how you could achieve this :
with tmp_table as
(
select rpt_no, first_value(column_name) over (order by timestamp asc rows unbounded predecing) as FirstItem
from log_table_b l
) select distinct tbl.table_name, firstItem
from prod_table tbl
join tmpTable on tmp_table.rpt_no = tbl.assignment_no;
You might want to find a more descriptive name to tmp_table
The issue is that you can only pass a reference from an outer query down to the next subquery level.
Here are a couple of alternatives:
select tbl.table_name,
(select min(column_name) keep (dense_rank first order by tstamp asc)
from log_table_b l
where tbl.assignment_no = l.rpt_no
) as "USERNAME"
from prod_table tbl;
select tbl.table_name,
l.username
from prod_table tbl
inner join (select rpt_no,
min(column_name) keep (dense_rank first order by tstamp asc) username
from log_table_b l
group by rpt_no)
on (tbl.assignment_no = l.rpt_no);
N.B. untested

Return non-null value from two tables in Oracle

I have two tables, T1 and T2 with same set of columns. I need to issue a query which will return me value of columns from either table whichever is not null. If both columns are null return null as the value of that column.
The columns are c1,c2,c3,cond1.
I issued the following query. The problem is that if one subquery fails the whole query fails. Somebody please help me. Probably there is another simple way.
SELECT NVL(T1.c1, T2.c1) c1,NVL(T1.c2, T2.c2) c2,NVL(T1.c3, T2.c3) c3
FROM (SELECT c1,c2,c3
FROM T1
WHERE cond1 = 'T10') T1
,(SELECT c1,c2,c3
FROM T2
WHERE cond1 = 'T200') T2 ;
You need something like this:
SELECT NVL((SELECT T1.c1
FROM T1
WHERE T1.c2 = 'T10'),
(SELECT T2.c1
FROM T2
WHERE T2.c2 = 'T200')) AS c1
FROM dual
Or you may prefer a full outer join:
SELECT NVL(T1.c1, T2.c1) AS c1
FROM T1 FULL OUTER JOIN T2 ON 1=1
WHERE T1.c2 = 'T10'
AND T2.c2 = 'T200'
Your result is logical. If the first table is null no combination of values will exist in the natural join.
EDIT. After some new requirements we can use a hack to get the row. Lets get all three possibilities, T1, T2 or all nulls and select the first one:
SELECT *
FROM ( (SELECT T1.*
FROM T1
WHERE T1.c2 = 'T10')
UNION ALL
(SELECT T2.*
FROM T2
WHERE T2.c2 = 'T200')
UNION ALL
(SELECT T2.*
FROM dual
LEFT JOIN T1 ON 1 = 0 ) )
WHERE ROWNUM = 1

why am I getting ORA-00936 error

I can run the following statements and get the correct results:
select moon_phase_text (sysdate)
from dual;
select date_day3
from aday3import t1,
aasum_report t2
where t1.date_day3 = t2.game_date;
This statement gives me a list of days ie 22-FEB-03
However when I am trying to update a field in a table with the following statement I get the error ORA-00936: missing expression
update aday3import
set moon_phase = select moon_phase_
(select date_day3
from aday3import t1,
aasum_report t2
where t1.date_day3 = t2.game_date )
from dual;
Instead of going for dual. Try concatenating the moon_phase_ in the select statement itself
update aday3import set moon_phase =
(select 'moon_phase_'||date_day3
from aday3import t1,
aasum_report t2
where t1.date_day3 = t2.game_date )

Resources