Join condition in Oracle query - oracle

I have following query which update the coulmn "tmp_activation_date" of rec_tmprecord table with max of actdate according to the conditions mentioned in query.
MERGE INTO rec_tmprecord
USING (SELECT rec.ID, MAX (act.actdate) AS tmpactivation_date
FROM rec_tmprecord rec INNER JOIN tmp_asset asset
ON asset.serial = rec.serialtemp
and upper (replace (asset.prodname, 'Ajink ')) = upper (replace (rec.prodnametemp, 'Ajink '))
and NVL(asset.release,'NF') = NVL(rec.tmprelease ,'NF')
and rec.serialtemp != 'aaa-aaaaaaaa'
LEFT JOIN tmp_acti_hist act
ON asset.tmp_id = act.tmp_row_id
WHERE rec.cust_id = 234567
GROUP BY rec.cust_id,asset.serial,rec.ID) new_values
ON (rec_tmprecord.ID = new_values.ID)
WHEN MATCHED THEN
UPDATE
SET tmp_activation_date = new_values.tmpactivation_date
;
But,When i analyzed the data of table "rec_tmprecord",i found that there are some null or blank values present in the "prodnametemp" column of "rec_tmprecord" table.But,column "prodname" of the table "tmp_asset" does not contain any null or blank values.
So,my join condition will fail at "upper (replace (asset.prodname, 'Ajink ')) = upper (replace (rec.prodnametemp, 'Ajink '))" condition and as a result "tmp_activation_date" of rec_tmprecord table will be updated with null value or blank value.
what my requirement is if "prodnametemp" is having null value and "prodname" contains some value then also "tmpactivation_date" will get calculated on the basis of other conditions mentioned in the query.
Anyhelp on this would be greatly appreciated.

Here is a modified version. I modified the join as follows:
upper (replace (asset.prodname, 'Ajink ')) = NVL(upper (replace (rec.prodnametemp, 'Ajink ')), upper (replace (asset.prodname, 'Ajink ')))
EDIT:
The join condition has been compressed, thanks to Alex Poole's suggestion.
Basically, if is NULL, then that condition would return TRUE, because then asset.prodname = asset.prodname.
MERGE INTO rec_tmprecord
USING (SELECT rec.ID, MAX (act.actdate) AS tmpactivation_date
FROM rec_tmprecord rec INNER JOIN tmp_asset asset
ON asset.serial = rec.serialtemp
and upper (replace (asset.prodname, 'Ajink ')) = upper (replace (NVL (rec.prodnametemp, asset.prodname), 'Ajink '))
and NVL(asset.release,'NF') = NVL(rec.tmprelease ,'NF')
and rec.serialtemp != 'aaa-aaaaaaaa'
LEFT JOIN tmp_acti_hist act
ON asset.tmp_id = act.tmp_row_id
WHERE rec.cust_id = 234567
GROUP BY rec.cust_id,asset.serial,rec.ID) new_values
ON (rec_tmprecord.ID = new_values.ID)
WHEN MATCHED THEN
UPDATE
SET tmp_activation_date = new_values.tmpactivation_date
;

Related

Oracle: Value from main query is not available in subquery

I have this query, and one of its column is a subquery that should be bringing a list of values using a listagg function. This list has its starting point as the S.ID_ORGAO_INTELIGENCIA value. The list is a should be, it always has values.
The listagg function is consuming an inline view that uses a window function to create the list.
select *
from (
SELECT DISTINCT S.ID_SOLICITACAO,
S.NR_PROTOCOLO_SOLICITACAO,
S.DH_INCLUSAO,
S.ID_USUARIO,
U.NR_CPF,
OI.ID_MODULO,
OI.ID_ORGAO_INTELIGENCIA,
OI.NO_ORGAO_INTELIGENCIA,
R.ID_ATRIBUICAO,
P.ID_PERMISSAO,
1 AS TIPO_NOTIFICACAO,
(
select LISTAGG(oc6.ID_ORGAO_INTELIGENCIA || '-' || oc6.ord || '-', '; ') WITHIN GROUP (ORDER BY oc6.ord) eai
from (
SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
oc1.SG_ORGAO_INTELIGENCIA,
rownum as ord
FROM TB_ORGAO_INTERNO oc1
WHERE oc1.DH_EXCLUSAO is null
-- THE VALUE FROM S.ID_ORGAO_INTELIGENCIA IS NOT AVAILBLE HERE
START WITH oc1.ID_ORGAO_INTELIGENCIA = S.ID_ORGAO_INTELIGENCIA
CONNECT BY prior oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA
) oc6) aproPrec
FROM TB_SOLICITACAO S
INNER JOIN TB_ORGAO_INTERNO OI ON S.ID_ORGAO_INTELIGENCIA = OI.ID_ORGAO_INTELIGENCIA
INNER JOIN TB_RELACIONAMENTO_ATRIBUICAO R
ON (R.ID_MODULO = OI.ID_MODULO AND R.ID_ORGAO_INTELIGENCIA IS NULL AND
R.ID_SOLICITACAO IS NULL)
INNER JOIN TB_PERMISSAO P
ON (P.ID_USUARIO = :usuario AND P.ID_ORGAO_INTELIGENCIA = :orgao AND
P.ID_ATRIBUICAO = R.ID_ATRIBUICAO)
INNER JOIN TB_USUARIO U ON (U.ID_USUARIO = S.ID_USUARIO)
WHERE 1 = 1
AND U.DH_EXCLUSAO IS NULL
AND P.DH_EXCLUSAO IS NULL
AND S.DH_EXCLUSAO IS NULL
AND OI.DH_EXCLUSAO IS NULL
AND R.ID_ATRIBUICAO IN :atribuicoes
AND P.ID_STATUS_PERMISSAO = 7
AND OI.ID_MODULO = 1
AND S.ID_STATUS_SOLICITACAO IN (1, 2, 5, 6)
and s.ID_ORGAO_INTELIGENCIA in (SELECT DISTINCT o.ID_ORGAO_INTELIGENCIA
FROM TB_ORGAO_INTERNO o
WHERE o.DH_EXCLUSAO IS NULL
START WITH o.ID_ORGAO_INTELIGENCIA = 3
CONNECT BY PRIOR o.ID_ORGAO_INTELIGENCIA = o.ID_ORGAO_INTELIGENCIA_PAI)
);
The problem is that the aproPrec column is always returning null as its result.
If I force the criteria to have the S.ID_ORGAO_INTELIGENCIA hardcoded, the list returns its true value.
If I chance this:
START WITH oc1.ID_ORGAO_INTELIGENCIA = S.ID_ORGAO_INTELIGENCIA
To this:
START WITH oc1.ID_ORGAO_INTELIGENCIA = 311
where 311 is the value that the S.ID_ORGAO_INTELIGENCIA column really has.
Is there a way to make this query works as 'I think' it should work?
To make it work, I changed the subquery by this another one:
(
select qt_.*
from (
SELECT QRY_NAME.*,
rownum as ord
FROM (
SELECT oc1.ID_ORGAO_INTELIGENCIA,
oc1.ID_ORGAO_INTELIGENCIA_PAI,
connect_by_root (oc1.ID_ORGAO_INTELIGENCIA) as root
FROM TB_ORGAO_INTERNO oc1
CONNECT BY NOCYCLE PRIOR oc1.ID_ORGAO_INTELIGENCIA_PAI = oc1.ID_ORGAO_INTELIGENCIA
) QRY_NAME
WHERE root = s.ID_ORGAO_INTELIGENCIA
) qt_
)

How to combine two query's results into one cell?

I have two different queries in oracle, I was able to show these queries side by side with cross join, but I want to see them in the same cell.
First query :
SELECT
pa.attrb_an_value
FROM
piece_attrb pa
WHERE
pa.piece_num_id = 1056436 AND
pa.attrb_code = 'PSP')
result : MCXTS
Second Query :
SELECT max(CAOSL.ATTRB_AN_VALUE)
FROM config_attrb_of_so_line caosl,
so_piece sp
WHERE sp.piece_num_id = 1056436
AND sp.so_id = caosl.so_id
AND sp.so_line_id = caosl.so_line_id
and SP.IS_ACTIVE_FLAG = 'Y'
AND CAOSL.ATTRB_CODE = 'GRS'
Result : DC0
I want to see like that in cell:
MCXTS - DC0
Concatenate them, then.
WITH
tab_1 (retval)
AS
-- first query
(SELECT pa.attrb_an_value
FROM piece_attrb pa
WHERE pa.piece_num_id = 1056436
AND pa.attrb_code = 'PSP'),
tab_2 (retval)
AS
-- second query
(SELECT MAX (caosl.attrb_an_value)
FROM config_attrb_of_so_line caosl, so_piece sp
WHERE sp.piece_num_id = 1056436
AND sp.so_id = caosl.so_id
AND sp.so_line_id = caosl.so_line_id
AND sp.is_active_flag = 'Y'
AND caosl.attrb_code = 'GRS')
-- final result
SELECT a.retval || ' - ' || b.retval as final_result
FROM tab_1 a CROSS JOIN tab_2 b

ORA-01427: single-row Subquery Returns More Than One Row for Update

Hi I am trying to execute but getting error single row subquery returns more than one row.
update upld_mktprice
set (upld_mktprice.orig_security, upld_mktprice.stk_exch, upld_mktprice.stk_group, upld_mktprice.instr_type) =
(select security.security,nvl(upld_mktprice.stk_exch,
nvl(security.stk_exch,'DIRECT')),
security.stk_group,
decode(upld_mktprice.source,'FOREX','X','S') as instr_type -- HLAMUAT-1457146: Passing DIRECT as a default value for HLAM. confirmed by Dheeren/Prasanth.
from v_security_all security
where upld_mktprice.security = Decode(security.asset_type,'OPT',security.stk_sec_id||' '||substr(security.security,instrb(security.security, ' ', 1,1)+3, length(security.security)),security.stk_sec_id)
and rectype = 'L'),
upld_mktprice.currency = nvl(upld_mktprice.currency,''),
upld_mktprice.value_date = nvl(upld_mktprice.value_date,''),
upld_mktprice.amc_code = 'AMC'
Where exists (select 1
from v_security_all security
where upld_mktprice.security = Decode(security.asset_type,'OPT',security.stk_sec_id||' '||substr(security.security,instrb(security.security, ' ', 1,1)+3, length(security.security)),security.stk_sec_id)
and rectype = 'L')
and upld_mktprice.orig_security is null
and upld_mktprice.user_id = 'SRINIVAS'
and upld_mktprice.source = 'MKTPRICEMAN';
I think the error pretty much speaks for itself. The portion of your query below is returning more than one row. There is no way for us to validate because we do not have the data that you have. It might also be a bit easier to troubleshoot if you used table aliases in your update statement.
(SELECT security.security,
NVL (upld_mktprice.stk_exch, NVL (security.stk_exch, 'DIRECT')),
security.stk_group,
DECODE (upld_mktprice.source, 'FOREX', 'X', 'S') AS instr_type -- HLAMUAT-1457146: Passing DIRECT as a default value for HLAM. confirmed by Dheeren/Prasanth.
FROM v_security_all security
WHERE upld_mktprice.security =
DECODE (security.asset_type,
'OPT', security.stk_sec_id
|| ' '
|| SUBSTR (security.security,
INSTRB (security.security,
' ',
1,
1)
+ 3,
LENGTH (security.security)),
security.stk_sec_id)
AND rectype = 'L')

Join not working in Oracle error is nctb : phone_number invalid identifier

I have 2 queries and want to retrieve data using join.
1st query is as below and retrieve column "Phone_Number"
SELECT p.VALUE "Phone_Number"
FROM netcracker_rdb.RDB_BPI rd
JOIN netcracker_rdb.RDB_PROD_OFFER rpo ON rd.PRODUCT_OFFERING = rpo.OBJECT_ID
JOIN netcracker_rdb.nc_params_pim p ON p.object_id = rd.object_id
AND attr_id = 9138903692913092143
2nd query is as below and retrieve 2 columns "MSISDN" and "shi"
SELECT TRIM (REPLACE (shid.msisdn, CHR (10), '')) "MSISDN", sc.imsi
FROM
(SELECT shl.iccid, MAX (shl.sim_history_id) AS shi
FROM ninas_dba.sim_history_tb shl
GROUP BY shl.iccid) shs,
ninas_dba.sim_history_tb shid,
ninas_dba.sim_history_tb sh,
ninas_dba.sim_card_tb sc,
ninas_dba.sim_card_type_tb sct,
ninas_dba.Tenant_tb smt
WHERE
shid.iccid = shs.iccid
AND sh.sim_history_id = shs.shi
AND shid.sim_status_id = 102
AND sc.iccid = shid.iccid
I want to join these 2 queries using 1st query's "Phone_Number" and 2nd query's "MSISDN" column
Get rid of double quotes. Nothing good in them.
Should be
SELECT "Phone_Number" --> double quotes here as well, if you used them ...
FROM ( (SELECT p.VALUE "Phone_Number" --> ... here
Or, as I suggested, no double quotes:
select phone_number
from ((select p.value phone_number
perhaps best to include the phone_number as a sub-query and include in the where statement?
so something like this....
SELECT
TRIM (REPLACE (shid.msisdn, CHR (10), '')) Phone_Number
FROM
(
SELECT
shl.iccid,
MAX (shl.sim_history_id) AS shi
FROM
ninas_dba.sim_history_tb shl
GROUP BY shl.iccid
) shs,
ninas_dba.sim_history_tb shid,
ninas_dba.sim_history_tb sh,
ninas_dba.sim_card_tb sc,
ninas_dba.sim_card_type_tb sct,
ninas_dba.Tenant_tb smt
WHERE
shid.iccid = shs.iccid
AND sh.sim_history_id = shs.shi
AND shid.sim_status_id = 102
AND sc.iccid = shid.iccid
AND TRIM (REPLACE (shid.msisdn, CHR (10), '')) in (
SELECT
p.VALUE
FROM netcracker_rdb.RDB_BPI rd
JOIN netcracker_rdb.RDB_PROD_OFFER rpo
ON rd.PRODUCT_OFFERING = rpo.OBJECT_ID
JOIN netcracker_rdb.nc_params_pim p
ON p.object_id = rd.object_id
AND attr_id = 9138903692913092143
)
As mentioned in other answers the quote is only necessary when there is a space in your alias so "Phone Number" would require quotes.
I also believe you need to re-evaluate what you are trying to achieve, there is a lot happening in this query to retrieve a single attribute. Perhaps there are different avenues to pursue to achieve the same result?
Hope it helps.

PL SQL [Err] ORA-12704: character set mismatch

I Have a two pl/sql query but there is no two coulmns at (1) queries.They are AcademicTitles and ManagerialTitles.So I gave they as default value 'YOK' at (1) query.
I want to UNION (1) and (2) queries.
Here is My Queries:
1-
SELECT
h1."IL_KODU",
h1."KURUM_ILI",
h1.ILCE_KODU,
h1."KURUM_ILCESI",
h1."KURUM_KODU",
h1."KURUM_ADI",
(
CASE
WHEN h1."STATU" = 'K' THEN
'Devlet'
END
) AS KURUM_STATU,
h1."KURUM_TUR_ADI",
br3."Type" AS Unvan,
br."BranchName" AS Brans,
'YOK' AS AkademikUnvan,
'YOK' AS IdariUnvan,
COUNT (1) AS Total
FROM KAMU_PERSONEL k1
INNER JOIN "SptsBranches" s1 ON s1."CkysBranchCode" = k1.BRANS_KODU
INNER JOIN "Branches" br ON s1."BranchId" = br."BranchId"
INNER JOIN "BranchBranchTypes" br2 ON br."BranchId" = br2."BranchId"
INNER JOIN "BranchTypes" br3 ON br3."BranchTypeId" = br2."BranchTypeId"
INNER JOIN HOSPITALS h1 ON h1.KURUM_KODU = k1.CALIS_BIRIM
GROUP BY
h1."IL_KODU",
h1."KURUM_ILI",
h1.ILCE_KODU,
h1."KURUM_ILCESI",
h1."KURUM_KODU",
h1."KURUM_ADI",
h1."STATU",
h1."KURUM_TUR_ADI",
br3."Type",
br."BranchName"
2-
SELECT
p3."IL_KODU",
p3."KURUM_ILI",
p3.ILCE_KODU,
p3."KURUM_ILCESI",
p3."KURUM_KODU",
p3."KURUM_ADI",
(
CASE
WHEN p3."STATU" = 'O' THEN
'Özel'
WHEN p3."STATU" = 'U' THEN
'Üniversite'
END
) AS KURUM_STATU,
p3."KURUM_TUR_ADI",
b2."Type" AS Unvan,
b1."BranchName" AS Brans,
u1."Title" AS AkademikUnvan,
u2."Title" AS IdariUnvan,
COUNT (1) AS Total
FROM
"SptsDatas" p1
INNER JOIN "PersonStatus" p2 ON p1."TcKimlik" = p2."Tckn"
INNER JOIN "Branches" b1 ON p1."Brans_BranchId" = b1."BranchId"
INNER JOIN "BranchTypes" b2 ON p1."Unvan_BranchTypeId" = b2."BranchTypeId"
INNER JOIN HOSPITALS p3 ON p2."HospitalCode" = p3."KURUM_KODU"
INNER JOIN "AcademicTitles" u1 ON u1."Id" = p1."AkademikUnvan_Id"
INNER JOIN "ManagerialTitles" u2 ON u2."Id" = p1."IdariUnvan_Id"
WHERE
p2."Statu" = 1
AND p3."AKTIF" = 1
GROUP BY
p3."IL_KODU",
p3."KURUM_ILI",
p3.ILCE_KODU,
p3."KURUM_ILCESI",
p3."KURUM_KODU",
p3."KURUM_ADI",
b1."BranchName",
b2."Type",
u1."Title",
u2."Title",
p3."STATU",
p3."KURUM_TUR_ADI"
When try to UNION two queries this error occuring.
[Err] ORA-12704: character set mismatch
How can I fix this error.
Thanks
My guess is that value of KURUM_STATU column in the second query is converted to NVARCHAR2, because of "Ö" and "Ü" in its value. As a result, Oracle tries to mix varchar2 with nvarchar2 giving the mentioned ORA error.
To confirm this, try to remove those characters from the statement and if it helps, convert the values explicitly to nvarchar2, or get rid of the trouble characters.
If you cast the two columns in second query that should solve it I believe.
In your second query try replacing
u1."Title" AS AkademikUnvan,
u2."Title" AS IdariUnvan,
with
CAST( u1."Title" AS varchar2(1000) ) AS AkademikUnvan,
CAST( u2."Title" AS varchar2(1000) ) AS IdariUnvan
Let me know how that goes.

Resources