I'm facing a problem in Oracle.
I had a SQL where some values were fixed. Now I started replacing them with values from a parameter-table. Some of these fixed values where in a NVL().
Simply said my statement is like this.
SELECT NVL(MAX(t.datefield), to_date('01011900','DDMMYYYY'))
FROM table t;
That works fine.
Now I want to replace the fixed date to a date from my parameter-table with a subselect, which doesn't work at all.
// Works
SELECT NVL(MAX(NULL), 'hello') FROM DUAL;
// Doesn't work
SELECT NVL(MAX(NULL), (SELECT 'hello' FROM DUAL)) FROM DUAL;
The error is:
ORA-00937: .... "not a single-group group function"
I have no idea how to group by a subselect.
Any help is very appreciated! Thanks!
You can't group by a sub-select. However, in order to achieve this your sub-select is only going to be able to return one row. So, change it into a Cartesian join and group by that.
SELECT NVL(MAX(NULL), str)
FROM DUAL
CROSS JOIN ( SELECT 'hello' as str FROM DUAL )
GROUP BY STR
More generally every column that is not included in an aggregate function must be included in the GROUP BY. Plus NVL() is bad; use COALESCE() or CASE instead.
Related
My RUBY code executes a oracle query in the following way, but I seem to be getting the error:
Java::JavaSql::SQLSyntaxErrorException: ORA-00979: not a GROUP BY expression
SELECT
"REQUESTS".*
FROM
"REQUESTS"
WHERE
(
customer_id = 1
AND request_method != 'OPTIONS'
AND request_time BETWEEN TO_TIMESTAMP('2021-10-29 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP(
'2021-11-05 23:59:59.000999',
'YYYY-MM-DD HH24:MI:SS.FF'
)
)
GROUP BY
"REQUESTS"."REQUEST_TIME"
Initially the code which is translated into the above mentioned select query is:
requests = Request.where("customer_id = ? AND request_method != ? AND request_time BETWEEN TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP(?,'YYYY-MM-DD HH24:MI:SS.FF')", customer.id, 'OPTIONS', start_time, end_time).group('date(request_time'))
The
.group('date(request_time') is translated in oracle to: GROUP BY date(request_time)
but it didn't seem to work either which was the original query, and the reason is because Oracle doesn't have this functionality , so I changed it and have been trying in differnt ways but can't seem to figure out why the group by expression wont work.
select * means "select all columns".
Group by clause says group by request_time, which is only one column, and that just won't work.
You'll have to apply group by to ALL columns (specified one-by-one), or - simpler - use select distinct.
Basically, we use group by when there's an aggregation in select column list. If there's none, you don't group by.
What you'll really do depends on what you want to do, i.e. which result you expect.
I am just wondering if use = sign operator with sub-query instead of IN
Is it correct way ? and meet the oracle standard ?
Example
select column_name from my_table_1 where id = (select max(id) from my_table_2);
The Difference is related to the number of rows returned. If you have only one row returned from nested sql you may prefer both = or in operators. But if multiple rows returned from nested query, use in operator.
So, in your sql example you may prefer using any of the operators. Since, max functions returns only one row.
As you are fetching maximum value from subquery to compare with id, Both(= and IN )will work fine. But If you are trying to fetch more than one row then you have to use IN keyword.
If you have 1 result in sub query you are fine with using = sign, except when data type is wrong, for example , checking with same data type of dummy VARCHAR2(1)
select * from dual where 'X' = (select max(dual.dummy) from dual);
Is similar to using in (also same explain plain)
select * from dual where 'X' in (select max(dual.dummy) from dual);
But checking with different/wrong data type will result with exception ORA-01722 Invalid number
select * from dual where 1 =(select max(dual.dummy) from dual);
I have learning informatica powercenter. I was able to do an INNER JOIN between two VIEWs. I added the INNER JOIN in the User Defined Join but still have to make correct changes in the Sql Query when click on Validate. Do I just need to only add to User Defined Join when I am joining VIEWS?
Here is my problem. I got another VIEWs which is one to many, so this will be my 3rd VIEW to add to the query. I got this running on TOAD. How do I add this to Infromatica? Do I just avoid the Sql Query section and add the entire query into User Defined Query? Do LISTAGG works in Informatica?
If not in the Query for LISTAGG (one-many relationship), is it better or is there a way to do this in the transformation like expression transformation?
Thanks.
This query is a SELECT, LISTAGG, CASE
SELECT PERSON_ID,
FIRST_NAME,
MIDDLE_NAME,
LAST_NAME,
LISTAGG(val,',') WITHIN GROUP (ORDER BY Table2.SKILL_SHORT_DESC )
FROM (SELECT DISTINCT Table1.PERSON_ID,
Table1.FIRST_NAME,
Table1.MIDDLE_NAME,
Table1.LAST_NAME,
(case
when Table2.SKILL_SHORT_DESC = '1' then '1:1'
when Table2.SKILL_SHORT_DESC = '2' then '2:2'
when Table2.SKILL_SHORT_DESC = '3' then '3:3'
when Table2.SKILL_SHORT_DESC = '4' then '4:4'
when Table2.SKILL_SHORT_DESC = '5' then '5:5'
when Table2.SKILL_SHORT_DESC = '6' then '6:6'
when Table2.SKILL_SHORT_DESC = '7' then '7:7'
when Table2.SKILL_SHORT_DESC = '8' then '8:8'
when Table2.SKILL_SHORT_DESC = '9' then '9:9'
else ''
end) as val
FROM Table1
LEFT JOIN Table2
ON Table2.PERSON_ID = Table1.PERSON_ID
)
GROUP BY PERSON_ID,FIRST_NAME,MIDDLE_NAME, LAST_NAME
Yes, LISTAGG should work. Assuming you are using oracle, it should work 10.x and higher version. Frankly, Informatica doesn't care what you write as SQL but its the database where SQL is being issued matters. You can write 'I am batman' and infa will return, 'Invalid syntax'.
Koushik
Please follow below steps,
Get any dummy source from the table
In source qualifier, remove all the ports and create the ports you required
In properties --> Sql query, add the query you have created. No need to provide any user defined joins
Below are the screen shots for better understanding.
I'm trying to execute a rather simple Oracle query against a table with a XMLTYPE column:
Select POB_CODPOL, CODSIS From (
Select T1.POB_CODPOL, EXTRACTVALUE(T1.POB_XMLPOL, '/Polbas/polfun[nomfun="filterBySystem"]/extpar[codele="codsis"]/valele/text()') CODSIS
From TDTX_POLITICA_CLOB T1
Where T1.POB_CODEMP = '001840'
)
Group By POB_CODPOL, CODSIS
This throws a ORA-00979 Not a GROUP BY Expression, which I don't really understand.
Even worse: when I execute the exact same query, but with a simplified XPATH query does work:
Select POB_CODPOL, CODSIS From (
Select T1.POB_CODPOL, EXTRACTVALUE(T1.POB_XMLPOL, 'Polbas/codpol/text()') CODSIS
From TDTX_POLITICA_CLOB T1
Where T1.POB_CODEMP = '001840'
)
Group By POB_CODPOL, CODSIS
It looks like Oracle doesn't like conditions like [nomfun="filterBySystem"] when using a GROUP BY (without the grouping clause, everything works fine).
Any idea on why this can be happening?
Edit: the result of the inner query is rather simple:
EXTRACTVALUE is deprecated.
Oracle recommends to use XMLQUERY, XMLTABLE for it.
This one should work:
WITH t as
(SELECT T1.POB_CODPOL, x.CODSIS
FROM TDTX_POLITICA_CLOB T1
NATURAL JOIN XMLTABLE('/Polbas/polfun[nomfun="filterBySystem"]/extpar[codele="codsis"]/valele'
PASSING POB_XMLPOL COLUMNS
CODSIS VARCHAR2(50) PATH '/') x
Where T1.POB_CODEMP = '001840')
SELECT POB_CODPOL, CODSIS
FROM t
GROUP BY POB_CODPOL, CODSIS;
There's a Bug 28588011 : "ORA-00979: NOT A GROUP BY EXPRESSION" WHEN TABLE FORMAT IS BINARY XML.
Severity 2 - Severe Loss of Service
Created 02-Sep-2018
Status 11 - Code/Hardware Bug (Response/Resolution)
WORKAROUND No
I guess they won't fix it. But the hint NO_XML_QUERY_REWRITE (that I use for other XML related bugs, too) worked for me.
I'm having a small issue with sorting the data returned from a query, with the aim of getting the oldest updated value in dataset so that I can update only that record. Here's what I'm doing:
WHERE ROWNUM = 1 AND TABLE1.ID != V_IGNOREID
AND TABLE1.LASTREADTIME = (SELECT MIN(TABLE1.LASTREADTIME) FROM TABLE1)
ORDER BY TABLE1.LASTREADTIME DESC;
It makes no difference as to whether the ORDER BY statement is included or not. If I only use the ROWNUM and equality checks, I get data, but it alternates between only two rows, which is why I'm trying to use the LASTREADTIME data (so that I can modify more than these two rows). Anybody have any thoughts on this, or any suggestions as to how I can use the MIN function effectively?
Cheers
select * from (
-- your original select without rownum and with order by
)
WHERE ROWNUM = 1
EDIT some explanation
I think the order by clause is applied on the resultset after the where clause. So if the rownum = 1 is in the same select statement with the order by, then it will be applied first and the order by will order only 1 row, which will be the first row of the unordered resultset.