Not a singlenot a single-group group function ORA-00937: Oracle - oracle

What can I do at the highest level to change this error
ORA-00937: not a single-group group function
00937. 00000 - "not a single-group group function"
*Cause:
*Action:
Error at Line: 3 Column: 5
select
year,
Net_TWRR_PERIOD,
round(((CASE WHEN MOD(SUM(CASE WHEN
( Net_TWRR_PERIOD ) <0 then 1 else 0 end ), 2 )=1 THEN -1 ELSE 1 END * EXP(SUM(LN(ABS(Net_TWRR_PERIOD)))))-1)*100,2)
from (select
year,
round(((CASE WHEN MOD(SUM(CASE WHEN (Net_TWRR ) <0 then 1 else 0 end ), 2 )=1 THEN -1 ELSE 1 END * EXP(SUM(LN(ABS(Net_TWRR)))))-1)*100,2) as Net_TWRR_PERIOD
from
(select ( net_rate_of_return / 100 + 1) as Net_TWRR,
year
from eom
WHERE id = '2'
and start_date < '09-September-2022'
) group by year order by year)

you are using the SUM functiion and the GROUP BY is missing in the outermost SQL.
create table eom(year number(4), start_date date, net_rate_of_return number (10,4), id number(4))
SELECT year,
Net_TWRR_PERIOD,
ROUND (
( ( CASE
WHEN MOD (
SUM (
CASE
WHEN (Net_TWRR_PERIOD) < 0 THEN 1
ELSE 0
END),
2) = 1
THEN
-1
ELSE
1
END
* EXP (SUM (LN (ABS (Net_TWRR_PERIOD)))))
- 1)
* 100,
2)
FROM ( SELECT year,
ROUND (
( ( CASE
WHEN MOD (
SUM (
CASE
WHEN (Net_TWRR) < 0 THEN 1
ELSE 0
END),
2) = 1
THEN
-1
ELSE
1
END
* EXP (SUM (LN (ABS (Net_TWRR)))))
- 1)
* 100,
2)
AS Net_TWRR_PERIOD
FROM (SELECT (net_rate_of_return / 100 + 1) AS Net_TWRR, year
FROM eom
WHERE id = '2' AND start_date < '09-September-2022')
GROUP BY year
ORDER BY year, Net_TWRR_PERIOD)
GROUP BY year, Net_TWRR_PERIOD

You have the outer query:
select year,
Net_TWRR_PERIOD,
round(
(
CASE
WHEN MOD(SUM(CASE WHEN Net_TWRR_PERIOD < 0 then 1 else 0 end ), 2)=1
THEN -1
ELSE 1
END
* EXP(SUM(LN(ABS(Net_TWRR_PERIOD))))
-1
) * 100,
2
)
from ( ... )
Which has a mix of aggregated columns and non-aggregated columns and you do not have a GROUP BY clause (in that outer query). You need to make sure all columns are either aggregated or contained in a GROUP BY.
So, change the outer query to:
select year,
Net_TWRR_PERIOD,
round(
(
CASE
WHEN MOD(SUM(CASE WHEN Net_TWRR_PERIOD < 0 then 1 else 0 end ), 2)=1
THEN -1
ELSE 1
END
* EXP(SUM(LN(ABS(Net_TWRR_PERIOD))))
-1
) * 100,
2
)
from ( ... )
GROUP BY year, Net_TWRR_PERIOD

Related

Calculate % based on a combination of count and stored values - Power BI

I have a basic table that looks like this:
DayNo. Customer AgentsInvolved CallID
0 AAA 1 1858
0 AAA 3 1859
2 AAA 1 1860
0 BBB 2 1862
0 CCC 1 1863
0 DDD 3 1864
9 DDD 1 1865
9 DDD 4 1866
I need to be able to find the % of customers who only contacted only once, and spoke to 1 agent only. So from the above example, out of 4 distinct customers only customer CCC falls into this category (1 call, 1 AgentInvolved)
So the Desired result would be: 1/4 or 25%
How can I create a Power BI measure to do this calc?
Try this measure:
Desired Result =
VAR summarizetable =
SUMMARIZECOLUMNS (
'table'[Customer],
"Calls", COUNT ( 'table'[CallID] ),
"Agents", SUM ( 'table'[AgentsInvolved] ),
"Day", SUM ( 'table'[DayNo.] )
)
RETURN
COUNTROWS (
FILTER ( summarizetable, [Calls] = 1 && [Agents] = 1 && [Day] = 0 )
)
/ COUNTROWS ( summarizetable )
The summarized table created on the fly in VAR summarizetable looks like this:
Here's another approach:
Measure =
SUMX(
VALUES(Table2[Customer]),
CALCULATE(
IF(
DISTINCTCOUNT(Table2[CallID]) = 1 &&
SUM(Table2[AgentsInvolved]) = 1,
1,
0
),
Table2[DayNo.] = 0
)
) /
DISTINCTCOUNT(Table2[Customer])
If you want to exclude the 0 day rows in the denominator as well, replace the last line with
CALCULATE(DISTINCTCOUNT(Table2[Customer]), Table2[DayNo.] = 0)
Desired Result =
VAR summarizetable =
SUMMARIZECOLUMNS (
'table'[AgentsInvolved],
'table'[DayNo.],
'table'[Customer],
"Calls", COUNT ( 'table'[CallID] )
)
)
RETURN
COUNTROWS (
FILTER ( summarizetable, [Calls] = 1 && 'table'[AgentsInvolved] = 1 && 'table'[DayNo.] = 0 )
) / DISTINCTCOUNT ( 'table'[Customer])

calculate percentage of two select counts

I have a query like
select count(1) from table_a where state=1;
it gives 20
select count(1) from table_a where state in (1,2);
it gives 25
I would like to have a query to extract percentage 80% (will be 20*100/25).
Is possible to have these in only one query?
I think without testing that the following SQL command can do that
SELECT SUM(CASE WHEN STATE = 1 THEN 1 ELSE 0 END)
/SUM(CASE WHEN STATE IN (1,2) THEN 1 ELSE 0 END)
as PERCENTAGE
FROM TABLE_A
or the following
SELECT S1 / (S1 + S2) as S1_PERCENTAGE
FROM
(
SELECT SUM(CASE WHEN STATE = 1 THEN 1 ELSE 0 END) as S1
,SUM(CASE WHEN STATE = 2 THEN 1 ELSE 0 END) as S2
FROM TABLE_A
)
or the following
SELECT S1 / T as S1_PERCENTAGE
FROM
(
SELECT SUM(CASE WHEN STATE = 1 THEN 1 ELSE 0 END) as S1
,SUM(CASE WHEN STATE IN (1,2) THEN 1 ELSE 0 END) as T
FROM TABLE_A
)
you have the choice for performance or readability !
Just as a slight variation on #schlebe's first query, you can continue to use count() by making that conditional:
select count(case when state = 1 then state end)
/ count(case when state in (1, 2) then state end) as result
from table_a
or multiplying by 100 to get a percentage instead of a decimal:
select 100 * count(case when state = 1 then state end)
/ count(case when state in (1,2) then state end) as percentage
from table_a
Count ignores nulls, and both of the case expressions default to null if their conditions are not met (you could have else null to make it explicit too).
Quick demo with a CTE for dummy data:
with table_a(state) as (
select 1 from dual connect by level <= 20
union all select 2 from dual connect by level <= 5
union all select 3 from dual connect by level <= 42
)
select 100 * count(case when state = 1 then state end)
/ count(case when state in (1,2) then state end) as percentage
from table_a;
PERCENTAGE
----------
80
Why the plsql tag? Regardless, i think what you need is:
(select count(1) from table_a where state=1) * 100 / (select count(1) from table_a where state in (1,2)) from dual

Convert to Laravel Query

I have query for query data. That is document.
"SELECT
zk_z_hako * CASE WHEN zk_n_iri> 0 THEN zk_n_iri ELSE 1 END
+ zk_z_bara
- ifnull(
sum(
ns_hako
* CASE WHEN zk_n_iri> 0 THEN zk_n_iri ELSE 1 END
* CASE WHEN ns_tr_kbn in (0,6) OR ( ns_tr_kbn = 1 AND ns_ns_kbn = 7) THEN 1
WHEN ns_tr_kbn in (1,7) THEN (-1)
ELSE 0
END
+ ns_bara
* CASE WHEN ns_tr_kbn in (0,6) OR ( ns_tr_kbn = 1 AND ns_ns_kbn = 7) THEN 1
WHEN ns_tr_kbn in (1,7) THEN (-1)
ELSE 0
END )
,0 ) AS TOTAL_BARA
FROM t_table1
LEFT JOIN t_table2
ON ns_kno = zk_kno
AND ns_show_flg = 0
AND ns_ymd > 'Date param'
WHERE zk_kno = Value param;
So I am not a master of Laravel. Now I need to convert this query for work with laravel. Anyone can help me?
And i have to try this query.
$squery = 'zk_z_hako * CASE WHEN zk_n_iri> 0 THEN zk_n_iri ELSE 1 END
+ zk_z_bara
ifnull(
sum(
ns_hako
* CASE WHEN zk_n_iri> 0 THEN zk_n_iri ELSE 1 END
* CASE WHEN ns_tr_kbn in (0,6) OR ( ns_tr_kbn = 1 AND ns_ns_kbn = 7) THEN 1
WHEN ns_tr_kbn in (1,7) THEN (-1)
ELSE 0
END
+ ns_bara
* CASE WHEN ns_tr_kbn in (0,6) OR ( ns_tr_kbn = 1 AND ns_ns_kbn = 7) THEN 1
WHEN ns_tr_kbn in (1,7) THEN (-1)
ELSE 0
END )
,0 ) AS TOTAL_BARA ';
$param1= '20160310';
$param2= '1972640100';
$results = DB::table('table1')
->select($squery)
->leftJoin('table2', function($join) use ($param1)
{
$join->on('table1.ns_kno', '=', 'table2.zk_kno');
$join->on('table1.ns_show_flg', '=', DB::raw(0));
$join->on('ns_ymd','>',DB::raw("'".$param1."'"));
})
->where('zk_kno', DB::raw($param2))
->toSql()
But it's return sql
"select `zk_z_hako` as `CASE` from `t_zaikmst` left join `t_nsyutrn` on `t_nsyutrn`.`ns_kno` = `t_zaikmst`.`zk_kno` and `t_nsyutrn`.`ns_show_flg` = 0 and `ns_ymd` > '20160310' where `zk_kno` = 1972640100"
i don't sure it true.
If you want to make custom select than you need to use raw queries as select parameter like this:
->select(\DB::raw($squery))

Oracle 11g Sql convert date from blob field

I have a problem in converting a date value stored in a blob field in Oracle 11g sql command. When i execute the sql:
select dump(HIGH_VALUE) from all_tab_columns where COLUMN_NAME='TARIH'
i receive the following result;
Typ=23 Len=7: 120,116,3,6,1,1,1
I know that these numbers represent a date (not datetime), but i don't know how to extract the date from this result.
Thanks in advance,
Alper
Oracle stores dates in tables as 7-bytes
byte 1 - century + 100
byte 2 - (year MOD 100 ) + 100
byte 3 - month
byte 4 - day
byte 5 - hour + 1
byte 6 - minute + 1
byte 7 - seconds+ 1
So 120,116,3,6,1,1,1 converts to:
byte 1 - century = 120 - 100 = 20
byte 2 - year = 116 - 100 = 16
byte 3 - month = 3
byte 4 - day = 6
byte 5 - hour = 1 - 1 = 0
byte 6 - minute = 1 - 1 = 0
byte 7 - seconds = 1 - 1 = 0
So 2016-03-06T00:00:00
Oracle Setup:
CREATE TABLE file_upload ( file_blob BLOB );
INSERT INTO file_upload VALUES (
utl_raw.cast_to_raw(
CHR(120) || CHR(116) || CHR(3) || CHR(6) || CHR(1) || CHR(1) || CHR(1)
)
);
Query:
SELECT DUMP( DBMS_LOB.SUBSTR( file_blob, 7, 1 ) ) AS dmp,
TO_DATE(
TO_CHAR(
( ASCII( SUBSTR( chars, 1, 1 ) ) - 100 ) * 100
+ ASCII( SUBSTR( chars, 2, 1 ) ) - 100,
'0000'
)
|| TO_CHAR( ASCII( SUBSTR( chars, 3, 1 ) ), '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 4, 1 ) ), '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 5, 1 ) ) - 1, '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 6, 1 ) ) - 1, '00' )
|| TO_CHAR( ASCII( SUBSTR( chars, 7, 1 ) ) - 1, '00' ),
'YYYYMMDDHH24MISS'
) AS converted_date
FROM (
SELECT file_blob,
UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR( file_blob, 7, 1 ) ) AS chars
FROM file_upload
);
Output:
DMP CONVERTED_DATE
------------------------------- -------------------
Typ=23 Len=7: 120,116,3,6,1,1,1 2016-03-06 00:00:00

Oracle performance tuning order by is taking time

Am having query,in which two fields and getting as output pps_id and total_weight. Here pps_id is the column from the table and total_weight we are calculating from inner query. after doing all process in query we are order by the query by total weight. Its taking more cost and response.Is there any way to improve this query performance.
SELECT PPS_ID, TOTAL_WEIGHT
FROM ( SELECT PPS_ID, TOTAL_WEIGHT
FROM (SELECT pps_id,
ROUND (
( ( (60 * name_pct_match / 100)
+ prs_weight
+ year_weight
+ dt_weight)
/ 90)
* 100)
total_weight
FROM (SELECT pps_id,
ROUND (func_compare_name ('aaaa',
UPPER (name_en),
' ',
60))
name_pct_match,
DECODE (prs_nationality_id, 99, 15, 0)
prs_weight,
10 mother_weight,
100 total_attrib_weight,
CASE
WHEN TO_NUMBER (
TO_CHAR (birth_date, 'yyyy')) =
1986
THEN
5
ELSE
0
END
year_weight,
CASE
WHEN TO_CHAR (
TO_DATE ('12-JAN-86',
'DD-MON-RRRR'),
'dd') =
TO_CHAR (birth_date, 'dd')
AND TO_CHAR (
TO_DATE ('12-JAN-86',
'DD-MON-RRRR'),
'mm') =
TO_CHAR (birth_date, 'mm')
THEN
10
WHEN TO_DATE ('12-JAN-86', 'DD-MON-RRRR') BETWEEN birth_date
- 6
AND birth_date
+ 6
THEN
8
WHEN TO_DATE ('12-JAN-86', 'DD-MON-RRRR') BETWEEN birth_date
- 28
AND birth_date
+ 28
THEN
5
WHEN TO_DATE ('12-JAN-86', 'DD-MON-RRRR') BETWEEN birth_date
- 90
AND birth_date
+ 90
THEN
3
ELSE
0
END
dt_weight
FROM individual_profile
WHERE birth_date = '12-JAN-86'
AND IS_ACTIVE = 1
AND gender_id = 1
AND ROUND (func_compare_name ('aaa',
UPPER (name_en),
' ',
60)) > 20))
WHERE TOTAL_WEIGHT >= 100
ORDER BY total_weight DESC)
WHERE ROWNUM <= 10
i have tried by splitting the query and put values in temp tables and tried but it also taking time. I want to improve the performance of the query

Resources