where statement not allowed with group by function - sql

I'm still a newbie with oracle, here I have a query that returns data like :
0.52
0.01
1
12
Desired result :
1
12
i have tried to do something like this in where part but it returns group function is not allowed here:
to_char((Max(start_time_timestamp+ (2/24))- p.port_statusmoddat), 999.999) >1
the query I'm working with:
select to_char((Max(start_time_timestamp+ (2/24))- p.port_statusmoddat), 999.999) as Diff
from ZAJBIREJ.UDR_ST r,directory_number d, CONTR_SERVICES_CAP C, MPUSNTAB SN, unicam.vw_contr_imsi_sim x, port p
where reject_reason_code = 'ISUBS'
and r.s_p_port_address = p.port_num (+)
and c.co_id = x.co_id (+)
and s_p_number_address = d.dn_num (+)
and d.dn_id =c.dn_id
AND C.SNCODE = sn.SNCODE
and C.MAIN_DIRNUM = 'X'
and c.cs_deactiv_date is null
and p.port_status = 'd'
AND nvl(C.cs_deactiv_date,'01-jan-2300') = (SELECT MAX(nvl(CA.cs_deactiv_date,'01-jan-2300'))
FROM CONTR_SERVICES_CAP CA, MPUSNTAB SNT
WHERE CA.DN_ID = D.DN_ID
AND SNT.SHDES = SN.SHDES)
group by reject_reason_code ,c.co_id, s_p_number_address,r.s_p_port_address,x.IMSI,p.port_status, p.port_statusmoddat

You need to use the HAVING clause:
group by reject_reason_code ,c.co_id, s_p_number_address, r.s_p_port_address,
x.IMSI, p.port_status, p.port_statusmoddat
having Max(start_time_timestamp+ (2/24))- p.port_statusmoddat >1
I also removed the redundant TO_CHAR as you want to test the number exceeds 1, not that a string of characters exceeds 1.

Related

GETTING ERROR-- ORA-00936:MISSING EXPRESSION for below query please help on this

SELECT CASE (SELECT Count(1)
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(
SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988')
)
WHEN 0 THEN
(
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27' )
WHEN 1 THEN
(
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
ELSE NULL
END
FROM dual;
You need to recreate your query and make sure to follow the flow of the clauses properly, please check the next two links to get a better understanding :
[ORA-00936: missing expression tips]
How do I address this ORA-00936 error?
Answer: The Oracle oerr utility notes this about the ORA-00936 error:
ORA-00936 missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
The ORA-00936 happens most frequently:
1 - When you forget list of the column names in your SELECT statement.
2. When you omit the FROM clause of the SQL statement.
ora-00936-missing-expression
I hope this can help you.
You cannot use a simple select query like this. You have to use a PL/SQL block like below -
DECLARE NUM_CNT NUMBER := 0;
BEGIN
SELECT Count(1)
INTO NUM_CNT
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988');
IF NUM_CNT = 0 THEN
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27';
ELSIF NUM_CNT = 1 THEN
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
END IF;
END;

Case expression with Boolean from PostgreSQL to SQL Server

I am translating a query from PostgreSQL to SQL Server. I didn't write the query in PostgreSQL and it's quite complicated for my knowledge so i don't understand every piece of it.
From my understand: we are trying to find the max version from p_policy and when insurancestatus = 7 or 14 / transactiontype = CAN, we compare two dates (whose format are BIG INT).
This is the PG Query:
SELECT *
FROM BLABLABLA
WHERE
pol.vnumber = (
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
-- ('CAN','RCA')
THEN pol1.veffectivedate = pol1.vexpirydate
ELSE pol1.veffectivedate <> pol1.vexpirydate
END
)
AND pol1.vrecordstatus NOT IN (30,254)
etc.
I am used to have a where statement where I compare it to a value. I understand here from the Case statement we will have a boolean, but still that must be compared to something?
Anyway the main purpose is to make it work in SQL, but I believe SQL can't read a CASE statement where THEN is a comparison.
This is what I tried:
SELECT *
FROM BLABLABLA
WHERE pol.vnumber =
(
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
WHERE sbuid = 4019
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
THEN CASE
WHEN pol1.veffectivedate = pol1.vexpirydate THEN 1
WHEN pol1.veffectivedate <> pol1.vexpirydate THEN 0
END
END
)
AND pol1.vrecordstatus NOT IN (30,254)
etc.
And then I get this error from SQL Server (which directly the last line of the current code - so after the double case statement)
Msg 4145, Level 15, State 1, Line 55
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.
Thank you !Let me know if it is not clear
I think you want boolean logic. The CASE expression would translate as:
(
(
(pol1.insurancestatus IN (7,14) OR pol1.transactiontype = 'CAN')
AND pol1.veffectivedate = pol1.vexpirydate
) OR (
NOT (pol1.insurancestatus IN (7,14) OR pol1.transactiontype = 'CAN')
AND pol1.veffectivedate <> pol1.vexpirydate
)
)
There are 2 main issues with your snippet, SQL Server-syntax-wise.
SELECT * FROM BLABLABLA WHERE
pol.vnumber = /* PROBLEM 1: we haven't defined pol yet; SQL Server has no idea what pol.vnumber is here, so you're going to get an error when you resolve your boolean issue */
(
SELECT MAX(pol1.vnumber)
FROM p_policy pol1
WHERE sbuid = 4019
AND ( CASE WHEN pol1.insurancestatus IN (7,14)
or pol1.transactiontype IN ('CAN')
THEN CASE
WHEN pol1.veffectivedate = pol1.vexpirydate THEN 1
WHEN pol1.veffectivedate <> pol1.vexpirydate THEN 0
END
END
) /* PROBLEM 2: Your case statement returns a 1 or a 0..
which means your WHERE is saying
WHERE sbuid = 4019
AND (1)
AND pol1.vrecordstatus NOT IN (30,254)
SQL Doesn't like that. I think you meant to add a boolean operation using your 1 or 0 after the parenthesis.
like this: */
= 1
AND pol1.vrecordstatus NOT IN (30,254)

Nested case conditionals in PostgreSQL, syntax error?

I use PostgreSQL and I would like to combine these two case conditions, but when I uncomment the code, I get a syntax error. This is not a difficult instruction. I want to divide or multiply the obtained number depending on the condition. How can I enter it so that the code is compiled?
SELECT
SUM(
CASE
WHEN transactions.recipient_account_bill_id = recipientBill.id AND recipientBill.user_id = 2
THEN 1
ELSE -1
END * transactions.amount_money
/* CASE
WHEN senderBillCurrency.id = recipientBillCurrency.id
THEN NULL
ELSE
CASE
WHEN recipientBillCurrency.base = true
THEN /
ELSE *
END senderBillCurrency.current_exchange_rate
END */
) as TOTAL
FROM transactions
LEFT JOIN bills AS senderBill ON senderBill.id = transactions.sender_account_bill_id
LEFT JOIN bills AS recipientBill ON recipientBill.id = transactions.recipient_account_bill_id
LEFT JOIN currency as senderBillCurrency ON senderBillCurrency.id = senderBill.currency_id
LEFT JOIN currency as recipientBillCurrency ON recipientBillCurrency.id = recipientBill.currency_id
WHERE 2 IN (senderBill.id, recipientBill.id)
You cannot create dynamic SQL expressions like that. A CASE expression cannot return an operator as if SQL was some sort of macro language. You can only return an expression.
You already used the following approach using 1 and -1 with your multiplication. Why not also use it with N and 1/N:
<some expression> * CASE WHEN condition THEN 1 / N ELSE N END
Or in your case:
<some expression> * CASE
WHEN senderBillCurrency.id = recipientBillCurrency.id THEN 1
WHEN recipientBillCurrency.base THEN 1 / senderBillCurrency.current_exchange_rate
ELSE senderBillCurrency.current_exchange_rate
END
Notice, you can put several WHEN clauses in a CASE expression. No need to nest them

Oracle function error

I am typing a function and i'm having an error here, I dont know what it is.
Could you give me a Hand ?
CREATE or replace FUNCTION function1(pIdReg in number,pIdPeriod in number) RETURN
number
IS
ncv number DEFAULT 0;
BEGIN
SELECT COUNT(IdPeriod)
INTO ncv
FROM(
SELECT a.IdPeriod, SUM(case when a.nt=0 then -a.valor else a.valor end) AS total --IF(a.nt=0,-a.valor,a.valor))
FROM dc a
JOIN emp b ON a.idDoc = b.idDoc
WHERE a.idReg = pIdReg AND a.IdPeriod < pIdPeriod AND
b.cc != 305 AND
(
b.cc = 302 AND(b.tipomov != 4)
OR
b.cc != 302 AND(1=1)-- emular el TRUE
)
AND a.type != 7
GROUP BY 1 HAVING total != 0
) AS ncv;
RETURN ncv;
END;
/
The error is SQL command not properly ended.
Sqldeveloper shows "AS ncv" underlined. Is there any problem with group by or having clause ?
I see three errors (though there may be more)
Oracle does not use the AS keyword for assigning table aliases. So AS ncv is invalid. If you want to use ncv as the alias for your subquery, you'd need to remove the AS (though it seems odd to choose an alias that happens to collide with the name of a local variable).
You cannot use positional notation in a GROUP BY clause. You would need to specify the name of the column(s) you want to group by not their position.
You cannot use aliases defined in your SELECT list in your HAVING clause. You would have to specify the aggregate function in the HAVING clause
Putting those three things together, I suspect you want something like this
CREATE or replace FUNCTION function1(pIdReg in number,pIdPeriod in number)
RETURN number
IS
ncv number DEFAULT 0;
BEGIN
SELECT COUNT(IdPeriod)
INTO ncv
FROM(
SELECT a.IdPeriod,
SUM(case when a.nt=0
then -a.valor
else a.valor
end) AS total --IF(a.nt=0,-a.valor,a.valor))
FROM dc a
JOIN emp b ON a.idDoc = b.idDoc
WHERE a.idReg = pIdReg AND a.IdPeriod < pIdPeriod
AND b.cc != 305
AND (
b.cc = 302 AND(b.tipomov != 4)
OR
b.cc != 302 AND(1=1)-- emular el TRUE
)
AND a.type != 7
GROUP BY a.IdPeriod
HAVING SUM(case when a.nt=0
then -a.valor
else a.valor
end) != 0
) ncv;
RETURN ncv;
END;
/
If you are still getting errors, it would be extremely helpful if you could edit your question and provide the DDL to create the tables that are referenced in this code. That would allow us to test on our systems whether the function compiles or not rather than trying to guess at the syntax errors

Oracle - Add rows together in one field

Using the following code. Keep getting the following error
Select distinct
ship_L.ship_ID,
ship_L.Item_Num,
C.sku,
C.ob_oid,
c.Container
From (
Select distinct
ob_oid,
sku,
substr((ltrim(sys_Connect_By_Path(trim(to_Cont),' / '))),2,(length(ltrim(sys_Connect_By_Path(trim(to_Cont),' / '))))) as Container
From (
Select distinct
Ob_oid,
sku,
To_Cont,
row_number() Over (Partition by sku order by to_Cont) -1 as seq
From (
Select distinct
ob_oid,
sku,
To_Cont
from elite_76_w1.ITH_f
--Where ob_oid = '237472'
-- and sku = '64154'
)
)
Where connect_By_Isleaf = 1
Connect by seq = Prior seq +1 and sku = Prior sku
Start with seq = 1
) C
Left Join elite_76_D.ship_L
on ship_L.ship_id = C.ob_oid
and ship_L.item_num = C.sku
WHere C.ob_oid = '237472'
and C.sku = '64154'
Getting this error:
ORA-01489: result of string concatenation is too long 01489. 00000 - " result of string concatenation is too long" *Cause: String concatenatin result is more than the maximun size. * Action: Make sure that the result is lees than the maximum size. Vendor Code 1489Error at line 3.
Start with:
SKU Location
64154 A153945
64154 A153943
64154 A153947
64154 A153946
64154 A153944
Need:
64154 A153944 / A153945 / A153946 / A153947
Thank you for all the help,
David
ORA-01489: result of string concatenation is too long means that part of your SQL is generating a string longer than 4000 characters, which is the limit of a VARCHAR2 in SQL.
You can't truncate the string in SQL (e.g. with SUBSTR), because SQL needs to construct the string before it sends it to the SUBSTR function; and it bails because it exceeds the limit.
To solve this you'll probably need to create your own PL/SQL function, in which you have a greater length limit (32k) for VARCHAR2s.