Related
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
I have create new table and insert sample data into the table. I want to get the top 10 products rank by amount weekly. I tried SQL Query but give the wrong data. I have shared the table, sample data, and SQL Query below.
I have a table:
CREATE TABLE product_table (
product_name VARCHAR2(20),
amount NUMBER,
datetime DATE
)
Sample Data:
INSERT INTO product_table (product_name, amount, datetime)
SELECT 'P1', 10000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P2', 15000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P3', 18000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P4', 11000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P5', 13000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P6', 16000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P7', 19000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P8', 20000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P9', 24000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P10',26000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P11',34000, TRUNC(SYSDATE, 'IW') FROM DUAL UNION ALL
SELECT 'P1', 8000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P2', 17000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P3', 22000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P4', 23000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P5', 26000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P6', 34000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P7', 31000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P8', 42000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P9', 54000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P10', 14000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P11', 19000, TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY FROM DUAL UNION ALL
SELECT 'P1', 8000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P2', 16000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P3', 21000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P4', 22000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P5', 25000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P6', 33000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P7', 32000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P8', 41000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P9', 53000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P10', 24000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P11', 29000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -1) FROM DUAL UNION ALL
SELECT 'P1', 7000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P2', 15000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P3', 20000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P4', 21000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P5', 24000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P6', 32000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P7', 31000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P8', 40000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P9', 52000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P10', 34000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P11', 39000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -2) FROM DUAL UNION ALL
SELECT 'P1', 6000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P2', 14000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P3', 19000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P4', 20000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P5', 23000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P6', 31000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P7', 30000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P8', 39000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P9', 51000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P10', 54000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL UNION ALL
SELECT 'P11', 69000, ADD_MONTHS(TRUNC(SYSDATE, 'IW'), -3) FROM DUAL;
Query:
SELECT
RANK() OVER (
ORDER BY SUM(
CASE
WHEN datetime >= TRUNC(SYSDATE, 'IW')
AND datetime < TRUNC(SYSDATE, 'IW') + INTERVAL '7' DAY
THEN 1
END
) DESC
) AS rank_this_week,
product_name,
SUM(AMOUNT) TOTAL_AMOUNT
FROM PRODUCT_TABLE
GROUP BY product_name, amount
ORDER BY AMOUNT DESC
FETCH FIRST 10 ROWS ONLY;
Result:
This query does not show correct Top 10 Products (by Amounts) - weekly Rank
db<>fiddle
Need Final Output Result in this format:
You haven't said what your expected output is; however, you appear to want to order by the weekly amount so you need to order by the rank_this_week column and not include amount in the GROUP BY clause:
SELECT RANK() OVER (
ORDER BY SUM(
CASE
WHEN datetime >= TRUNC(SYSDATE, 'IW')
AND datetime < TRUNC(SYSDATE, 'IW') + INTERVAL '7' DAY
THEN amount
END
) DESC
) AS rank_this_week,
product_name,
SUM(
CASE
WHEN datetime >= TRUNC(SYSDATE, 'IW')
AND datetime < TRUNC(SYSDATE, 'IW') + INTERVAL '7' DAY
THEN amount
END
) AS total_amount_this_week,
SUM(AMOUNT) TOTAL_AMOUNT
FROM PRODUCT_TABLE
GROUP BY product_name
ORDER BY rank_this_week
FETCH FIRST 10 ROWS ONLY;
Which, for the sample data, outputs:
RANK_THIS_WEEK
PRODUCT_NAME
TOTAL_AMOUNT_THIS_WEEK
TOTAL_AMOUNT
1
P11
34000
190000
2
P10
26000
152000
3
P9
24000
234000
4
P8
20000
182000
5
P7
19000
143000
6
P3
18000
100000
7
P6
16000
146000
8
P2
15000
77000
9
P5
13000
111000
10
P4
11000
97000
db<>fiddle here
After you posted a comment and displayed desired result, here's one option. Read comments within code.
SQL> with
2 -- Each DATES CTE returns desired "date" value
3 dates_tw as (select to_char(sysdate, 'yyyy iw') this_week from dual),
4 dates_pw as (select to_char(sysdate - 7, 'yyyy iw') previous_week from dual),
5 dates_lm as (select trunc(add_months(sysdate, -1), 'mm') last_month from dual),
6 dates_ma2 as (select trunc(add_months(sysdate, -2), 'mm') two_months_ago from dual),
7 dates_ma3 as (select trunc(add_months(sysdate, -3), 'mm') three_months_ago from dual),
8 sums as
9 -- compute total amount for reach "date" value from DATES CTEs, hence CROSS JOIN.
10 -- As DATES CTEs contain a single row, that shouldn't be too bad (performance wise)
11 (select p.product_name,
12 sum(case when to_char(p.datetime, 'yyyy iw') = tw.this_week then amount else 0 end) sum_tw,
13 sum(case when to_char(p.datetime, 'yyyy iw') = pw.previous_week then amount else 0 end) sum_pw,
14 sum(case when trunc(p.datetime, 'mm') = lm.last_month then amount else 0 end) sum_lm,
15 sum(case when trunc(p.datetime, 'mm') = ma2.two_months_ago then amount else 0 end) sum_ma2,
16 sum(case when trunc(p.datetime, 'mm') = ma3.three_months_ago then amount else 0 end) sum_ma3
17 from product_table p cross join dates_tw tw
18 cross join dates_pw pw
19 cross join dates_lm lm
20 cross join dates_ma2 ma2
21 cross join dates_ma3 ma3
22 group by product_name
23 ),
24 ranks as
25 -- rank products per each total amount
26 (select s.product_name,
27 rank() over (order by sum_tw desc) rnk_tw,
28 rank() over (order by sum_pw desc) rnk_pw,
29 rank() over (order by sum_lm desc) rnk_lm,
30 rank() over (order by sum_ma2 desc) rnk_ma2,
31 rank() over (order by sum_ma3 desc) rnk_ma3
32 from sums s
33 )
34 -- finally, return only product that "now" rank as the first 5 (or as many as you want),
35 -- and display their rank for other dates
36 select rnk_tw as "rank this week",
37 product_name,
38 rnk_pw as "previous week",
39 rnk_lm as "last month",
40 rnk_ma2 as "2 months ago",
41 rnk_ma3 as "3 months ago"
42 from ranks
43 where rnk_tw <= 5
44 order by rnk_tw;
rank this week PRODUCT_NAME previous week last month 2 months ago 3 months ago
-------------- -------------------- ------------- ---------- ------------ ------------
1 P11 8 5 3 1
2 P10 10 7 4 2
3 P9 1 1 1 3
4 P8 2 2 2 4
5 P7 4 4 6 6
SQL>
In Oracle I would like to build a query that counts how many Mondays and Thursdays have gone by from a starting date counting both together.
For example:
from 20-MAY-18 to today (Thursday 31-MAY-18)
There has been the total count of 4 Mondays and Thursdays (2 Mondays and 2 Thursdays) have passed by from May 20 until today. I want to 4 in return in this query. If this query ran yesterday (Wednesday 30-MAY-18), I want to get 3 counts.
I am thinking subtracting the weeks from today minus 20-MAY-18
Maybe something like this:
select ( TRUNC( SYSDATE, 'IW' ) - TRUNC( TO_DATE('20-MAY-18'), 'IW' ) ) / 7 * 2 from dual;
I times it by two because of the monday and thursday. If the thurday hasn't come up yet then it gives the wrong result because of this week.
I cannot figure out to count the weekdays that have past this week to times it by the week count.
I need to be able also to change the days selected and not get stuck with only Monday and Thursday.
Maybe this will help. You can add more logic to it. I'm not sure why this has to return 3 if ran on May 30th. What is he idea? Your start/end dates are the same and number of days between also the same no matter when you run it. What should happen if his run May 30?
WITH mon_thur AS
(
SELECT to_date('20-MAY-2018') + LEVEL-1 start_date
, to_date('31-MAY-2018') end_date
, to_date('31-MAY-2018') - to_date('20-MAY-2018') days_between
FROM dual
CONNECT BY LEVEL <= to_date('31-MAY-2018') - to_date('20-MAY-2018')+1 -- days_between+1
)
SELECT count(*) number_of_mon_thu FROM
(
SELECT start_date, to_char(start_date, 'D') d_date
FROM mon_thur
)
WHERE d_date IN (2, 4)
/
The output is 4. You can replace the 'D' format to 'DY' and replace 2, 4 with WHERE d_date IN ('MON', 'THU').
You can use this to calculate the value:
Calculate the number of full days between the Monday of the week containing the start date and the Monday of this week:
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) )
Divide it by 7 to get the number of full weeks:
/ 7
Multiply it by the number of days you want to match per week
* 2
Then adjust it to remove the Mondays and Thursdays that have been counted before the start date. This is 0 adjustment if the start day is Monday, 1 for Tuesday-Thursday and 2 for Friday-Sunday:
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, -- Monday
1, 1, -- Tuesday
2, 1, -- Wednesday
3, 1, -- Thursday
4, 2, -- Friday
5, 2, -- Saturday
6, 2 -- Sunday
)
Then adjust it to include the days from the Monday of this current week to today:
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 1, -- Monday
1, 1, -- Tuesday
2, 1, -- Wednesday
3, 2, -- Thursday
4, 2, -- Friday
5, 2, -- Saturday
6, 2 -- Sunday
)
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( start_date ) AS
SELECT DATE '2018-05-20' + LEVEL - 1
FROM DUAL
CONNECT BY DATE '2018-05-20' + LEVEL - 1 <= SYSDATE;
Query 1:
SELECT start_date,
TO_CHAR( start_date, 'DY' ) As day,
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 2
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, 1, 1, 2, 1, 3, 1, 4, 2, 5, 2, 6, 2 )
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 1, 1, 1, 2, 1, 3, 2, 4, 2, 5, 2, 6, 2 ) AS num_mon_and_thurs
FROM table_name
Results:
| START_DATE | DAY | NUM_MON_AND_THURS |
|----------------------|-----|-------------------|
| 2018-05-20T00:00:00Z | SUN | 4 |
| 2018-05-21T00:00:00Z | MON | 4 |
| 2018-05-22T00:00:00Z | TUE | 3 |
| 2018-05-23T00:00:00Z | WED | 3 |
| 2018-05-24T00:00:00Z | THU | 3 |
| 2018-05-25T00:00:00Z | FRI | 2 |
| 2018-05-26T00:00:00Z | SAT | 2 |
| 2018-05-27T00:00:00Z | SUN | 2 |
| 2018-05-28T00:00:00Z | MON | 2 |
| 2018-05-29T00:00:00Z | TUE | 1 |
| 2018-05-30T00:00:00Z | WED | 1 |
| 2018-05-31T00:00:00Z | THU | 1 |
What if I want to change it instead of monday and thursday to be tuesday, wednesday, saturday? How do I do that?
SELECT start_date,
TO_CHAR( start_date, 'DY' ) As day,
( TRUNC( SYSDATE, 'IW' ) - TRUNC( start_date, 'IW' ) ) / 7 * 3
- DECODE( TRUNC( start_date ) - TRUNC( start_date, 'IW' ),
0, 0, 1, 0, 2, 1, 3, 2, 4, 2, 5, 2, 6, 3 )
+ DECODE( TRUNC( SYSDATE ) - TRUNC( SYSDATE, 'IW' ),
0, 0, 1, 1, 2, 2, 3, 2, 4, 2, 5, 3, 6, 3 ) AS num_tue_wed_sat
FROM table_name;
SQLFIDDLE
whats is wrong with this query.
I need to get all hours of the 24 hours period to count hits per hour.
I want to make a case when 0-24 but I can not do the first work
SELECT
(
CASE WHEN (
CAST(TO_CHAR(dg_user_acess.dt_user_acess, 'HH24') >= '00')
AND
CAST(TO_CHAR(dg_user_acess.dt_user_acess, 'HH24') < '01')
)
THEN ('00:00 as 01:00')
ELSE '0' END
) as hour,
count(*)
FROM dg_user_acess
GROUP by hour
i get the error
Erro de SQL: ORA-00905: palavra-chave não encontrada
00905. 00000 - "missing keyword"
the table data is like this
pk| dt_user_acess
01| 2014-10-21 08:30:12
02| 2014-10-21 08:40:27
03| 2014-10-21 08:56:18
04| 2014-10-21 09:15:19
05| 2014-10-21 10:42:48
...
and the result I would like something like this (not write the case when all schedulesin query to not pollute the code)
'00:00 as 01:00' 0
'01:00 as 02:00' 0
'02:00 as 03:00' 0
'03:00 as 04:00' 0
'04:00 as 05:00' 0
'05:00 as 06:00' 0
'06:00 as 07:00' 0
'07:00 as 08:00' 0
'08:00 as 09:00' 3
'09:00 as 10:00' 1
'10:00 as 11:00' 1
'11:00 as 12:00' 0
'12:00 as 13:00' 0
'13:00 as 14:00' 0
'14:00 as 15:00' 0
'15:00 as 16:00' 0
'16:00 as 17:00' 0
'17:00 as 18:00' 0
'18:00 as 19:00' 0
'19:00 as 20:00' 0
'20:00 as 21:00' 0
'21:00 as 22:00' 0
'22:00 as 23:00' 0
'23:00 as 23:59' 0
whats is wrong with this query [?]
You have many (more or less severe) issues with your query -- in no particular order:
The correct syntax for CAST is CAST(value AS type)
You use hour as a column name, but it is a reserved word
You compare strings where it is probably numbers that you should compare
You seems to expect a "dense" result set, but as you don't use a join, there is no chance for the result set to have more rows than the original table (probably less in fact, as you GROUP BY)
Given your needs, you probably missed the EXTRACT(HOUR FROM ...) function. In order to extract all the "hits" for an hour, you would write that:
SELECT
EXTRACT(HOUR FROM dg_user_acess.dt_user_acess) as "hour"
FROM dg_user_acess
As you need to COUNT them (and since you cannot use an alias in a GROUP BY clause) you might use a sub-query. Don't worry too much about that: Oracle is smart enough to optimize that kind of request:
SELECT "hour", count(*) "cnt"
FROM (
SELECT
EXTRACT(HOUR FROM dg_user_acess.dt_user_acess) as "hour"
FROM dg_user_acess
) V
GROUP BY "hour";
Finally, as you need a dense output (i.e.: with all hours in the range 0-23), my option would be to use a join on a generated table:
SELECT "hour", NVL("cnt",0) "cnt"
FROM (
SELECT LEVEL "hour" FROM DUAL
CONNECT BY LEVEL < 24
) CLOCK
LEFT JOIN (
SELECT "hour", count(*) "cnt"
FROM (
SELECT
EXTRACT(HOUR FROM dg_user_acess.dt_user_acess) as "hour"
FROM dg_user_acess
) V
GROUP BY "hour"
) G
USING ("hour")
ORDER BY "hour";
All of this leads to rather complexly nested queries. But this has the benefit of being easy to write incrementally as you just see it. Now that I showed the basic building blocks, perhaps we could do a better job. Maybe that:
SELECT CLOCK."hour", COUNT(dg_user_acess.dt_user_acess) "cnt"
FROM (
SELECT LEVEL "hour" FROM DUAL
CONNECT BY LEVEL < 24
) CLOCK
LEFT JOIN dg_user_acess
ON CLOCK."hour" = EXTRACT(HOUR FROM dg_user_acess.dt_user_acess)
GROUP BY CLOCK."hour"
ORDER BY CLOCK."hour";
Depending your schema and data, this might or might not perform better than the previous version. Feel free to take some time to experiment all these queries on http://sqlfiddle.com/#!4/678a5/17
i get some result changing the group by and the condition of the case (and remove the cast).
I do not know if it's the best way to do this, but it worked
SELECT
(
CASE WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '00:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '01:00' ) THEN ('00:00 as 01:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '01:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '02:00' ) THEN ('01:00 as 02:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '02:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '03:00' ) THEN ('02:00 as 03:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '03:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '04:00' ) THEN ('03:00 as 04:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '04:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '05:00' ) THEN ('04:00 as 05:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '05:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '06:00' ) THEN ('05:00 as 06:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '06:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '07:00' ) THEN ('06:00 as 07:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '07:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '08:00' ) THEN ('07:00 as 08:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '08:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '09:00' ) THEN ('08:00 as 09:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '09:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '10:00' ) THEN ('09:00 as 10:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '10:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '11:00' ) THEN ('10:00 as 11:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '11:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '12:00' ) THEN ('11:00 as 12:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '12:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '13:00' ) THEN ('12:00 as 13:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '13:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '14:00' ) THEN ('13:00 as 14:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '14:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '15:00' ) THEN ('14:00 as 15:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '15:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '16:00' ) THEN ('15:00 as 16:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '16:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '17:00' ) THEN ('16:00 as 17:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '17:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '18:00' ) THEN ('17:00 as 18:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '18:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '19:00' ) THEN ('18:00 as 19:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '19:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '20:00' ) THEN ('19:00 as 20:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '20:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '21:00' ) THEN ('20:00 as 21:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '21:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '22:00' ) THEN ('21:00 as 22:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '22:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '23:00' ) THEN ('22:00 as 23:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '23:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '23:59' ) THEN ('23:00 as 23:59')
ELSE '0' END
) as hora,
count(*) as total
FROM dg_usuario_acesso
JOIN dg_usuario_sessao
ON dg_usuario_sessao.cd_usuario_sessao = dg_usuario_acesso.cd_usuario_sessao
WHERE dg_usuario_acesso.dt_usuario_acesso >= to_date('2014-09-19 00:00', 'YYYY-MM-DD HH24:Mi')
AND dg_usuario_acesso.dt_usuario_acesso <= to_date('2014-09-20 15:07', 'YYYY-MM-DD HH24:Mi')
AND dg_usuario_sessao.cd_usuario NOT IN (0,1,138)
group by (CASE WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '00:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '01:00' ) THEN ('00:00 as 01:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '01:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '02:00' ) THEN ('01:00 as 02:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '02:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '03:00' ) THEN ('02:00 as 03:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '03:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '04:00' ) THEN ('03:00 as 04:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '04:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '05:00' ) THEN ('04:00 as 05:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '05:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '06:00' ) THEN ('05:00 as 06:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '06:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '07:00' ) THEN ('06:00 as 07:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '07:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '08:00' ) THEN ('07:00 as 08:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '08:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '09:00' ) THEN ('08:00 as 09:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '09:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '10:00' ) THEN ('09:00 as 10:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '10:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '11:00' ) THEN ('10:00 as 11:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '11:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '12:00' ) THEN ('11:00 as 12:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '12:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '13:00' ) THEN ('12:00 as 13:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '13:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '14:00' ) THEN ('13:00 as 14:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '14:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '15:00' ) THEN ('14:00 as 15:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '15:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '16:00' ) THEN ('15:00 as 16:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '16:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '17:00' ) THEN ('16:00 as 17:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '17:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '18:00' ) THEN ('17:00 as 18:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '18:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '19:00' ) THEN ('18:00 as 19:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '19:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '20:00' ) THEN ('19:00 as 20:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '20:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '21:00' ) THEN ('20:00 as 21:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '21:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '22:00' ) THEN ('21:00 as 22:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '22:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '23:00' ) THEN ('22:00 as 23:00')
WHEN (TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') >= '23:00' AND TO_CHAR(dg_usuario_acesso.DT_USUARIO_ACESSO, 'HH24:Mi') < '23:59' ) THEN ('23:00 as 23:59')
ELSE '0' END
)
order by 1
and I got the result I would like
hour Total hits
00:00 as 01:00 10
04:00 as 05:00 8
07:00 as 08:00 4
08:00 as 09:00 14
09:00 as 10:00 84
10:00 as 11:00 25
11:00 as 12:00 14
12:00 as 13:00 7
13:00 as 14:00 5
14:00 as 15:00 7
15:00 as 16:00 22
16:00 as 17:00 19
17:00 as 18:00 28
18:00 as 19:00 7
19:00 as 20:00 16
21:00 as 22:00 2
23:00 as 23:59 2
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