I have the records using the query
SELECT trunc(createdon,'hh') CREATEDON,count(*)
FROM WHERE LABSTATUS=1 AND
CREATEDON >=TO_DATE('01/07/2010 10','DD/MM/YYYY hh')
GROUP BY trunc(createdon,'hh')
in an hourly basis.. I need to place the count value in corresponding time column in the grid.
How can I do?? any idea
You can do it like this:
Hours are in columns
SELECT TRUNC(createdon,'hh'), SUM(CASE WHEN hh=1 THEN 1 ELSE 0) h1,
SUM(CASE WHEN hh=2 THEN 1 ELSE 0) h2 .....
FROM TABLle1,
(SELECT 1 AS hh FROM dual
UNION
SELECT 2 AS hh FROM dual
UNION
SELECT 3 AS hh FROM dual
....
) hours
WHERE LABSTATUS=1 AND CREATEDON >=TO_DATE('01/07/2010 10','DD/MM/YYYY hh') AND
TRUNC(createdon,'hh')= hours.hh
GROUP BY TRUNC(createdon,'hh')
Hours are in rows:
SELECT hours.hh, SUM(CASE WHEN TRUNC(createdon,'hh')= hours.hh THEN 1 ELSE 0 END) hh,
FROM TABLle1,
(SELECT 1 AS hh FROM dual
UNION
SELECT 2 AS hh FROM dual
UNION
SELECT 3 AS hh FROM dual
....
) hours
WHERE LABSTATUS=1 AND CREATEDON >=TO_DATE('01/07/2010 10','DD/MM/YYYY hh')
GROUP BY hours.hh
This query will result like this
row 1 12
row 2 0
row 3 4
...
Related
I want to add this query in stored procedure but it gives an error: ORA-00913: too many values
Select SUM(CONNMASS.CONN_BILLAMOUNT) as Revenuebilled,
count(CONNMASS.CONN_BILLEDUNITS) AS volumebilled,
count(MASSBILL.BM_lo_id) as normalbilled,
( SELECT COUNT(CASE WHEN SRM_DISCON_STATUS_ID = 3 THEN 1 END) AS ACTIVE_CONNECTIONS,
COUNT(CASE WHEN SRM_DISCON_STATUS_ID = 2 THEN 1 END) AS DISC_CONNECTIONS
from Connection_master)
from CONNECTION_MASTER CONNMASS
left join BILLING_MASTER MASSBILL
on MASSBILL.CONN_SERVICE_NO = CONNMASS.CONN_SERVICE_NO;
The problem is that you are selecting multiple values in the sub-query. You can only select a single value in a sub-query in the SELECT clause.
However, you do not need the sub-query and appear to want:
Select SUM(CONNMASS.CONN_BILLAMOUNT) as Revenuebilled,
count(CONNMASS.CONN_BILLEDUNITS) AS volumebilled,
count(MASSBILL.BM_lo_id) as normalbilled,
COUNT(CASE SRM_DISCON_STATUS_ID WHEN 3 THEN 1 END) AS ACTIVE_CONNECTIONS,
COUNT(CASE SRM_DISCON_STATUS_ID WHEN 2 THEN 1 END) AS DISC_CONNECTIONS
from CONNECTION_MASTER CONNMASS
left join BILLING_MASTER MASSBILL
on MASSBILL.CONN_SERVICE_NO = CONNMASS.CONN_SERVICE_NO;
If you did want the sub-queries then:
Select SUM(CONNMASS.CONN_BILLAMOUNT) as Revenuebilled,
count(CONNMASS.CONN_BILLEDUNITS) AS volumebilled,
count(MASSBILL.BM_lo_id) as normalbilled,
( SELECT COUNT(CASE SRM_DISCON_STATUS_ID WHEN 3 THEN 1 END)
from Connection_master) AS ACTIVE_CONNECTIONS,
( SELECT COUNT(CASE SRM_DISCON_STATUS_ID WHEN 2 THEN 1 END)
from Connection_master) AS DISC_CONNECTIONS
from CONNECTION_MASTER CONNMASS
left join BILLING_MASTER MASSBILL
on MASSBILL.CONN_SERVICE_NO = CONNMASS.CONN_SERVICE_NO;
all the below results are not related to each other wheras we cannot use any condition.
ID
----------
1
2
3
4
5
6
7
7 rows selected.
NAME
-----------------
SRUJAN
DEERAJ
VINEETH
CHANIKYA
LAVANYA
KAVITHA
BUNNY
7 rows selected.
AGE
----------
23
24
26
25
29
28
24
7 rows selected.
ADDRESS
-------------
NAGARAM
BANDLAGUDA
UPPAL
KUKATPALLY
HB COLONY
MOULALI
BOUDHA NAGAR
7 rows selected.
SALARY
----------
12000
13000
14000
15000
16000
17000
18000
7 rows selected.
I USED
SQL>select id,name,age,address,salary from table1,table2,table3,table4,table5;
but it showing 16807 rows selected
i want to get only one table.
please suggest a query.
The only possible join between 2 tables having only 1 columns and both having no relation is cross join. You cannot avoid it. And the same you are getting when you tried to join. The best way for you is to create a sequence as ID and then call it in your select statement of table2.
CREATE SEQUENCE TEST_SEQ
START WITH 1
MAXVALUE 9999999999999999999999999999
MINVALUE 1
NOCYCLE;
select TEST_SEQ.nextval ID,col1 NAME
from table2;
Here is one way, using inner joins. This solution matches the lowest id with the first name in alphabetical order, the lowest age, etc.
If instead of this ordered matching you need random matching, that is easy to do as well: in the over... clause of the prep tables, change the order by clause to order by dbms_random.value() (in all places).
In the solution below I use only the first three tables, but the same works for any number of input tables.
with
tbl_id ( id ) as (
select 1 from dual union all
select 2 from dual union all
select 3 from dual union all
select 4 from dual union all
select 5 from dual union all
select 6 from dual union all
select 7 from dual
),
tbl_name ( name ) as (
select 'SRUJAN' from dual union all
select 'DEERAJ' from dual union all
select 'VINEETH' from dual union all
select 'CHANIKYA' from dual union all
select 'LAVANYA' from dual union all
select 'KAVITHA' from dual union all
select 'BUNNY' from dual
),
tbl_age ( age ) as (
select 23 from dual union all
select 24 from dual union all
select 26 from dual union all
select 25 from dual union all
select 29 from dual union all
select 28 from dual union all
select 24 from dual
),
prep_id ( id, rn ) as (
select id, row_number() over (order by id) from tbl_id
),
prep_name ( name, rn ) as (
select name, row_number() over (order by name) from tbl_name
),
prep_age ( age , rn ) as (
select age, row_number() over (order by age) from tbl_age
)
select i.id, n.name, a.age
from prep_id i inner join prep_name n on i.rn = n.rn
inner join prep_age a on i.rn = a.rn
;
Output:
ID NAME AGE
---------- -------- ----------
1 BUNNY 23
2 CHANIKYA 24
3 DEERAJ 24
4 KAVITHA 25
5 LAVANYA 26
6 SRUJAN 28
7 VINEETH 29
7 rows selected
I have a table that contains two time stamp t1(event open date) and t2(event close date) and a primary key eventid.
If event is open then t2 will be null whenever even gets closed the same row will be get updated with event closure date t2.
For example I want to check how many issues are open on every day bases on opened date (t1) from 01-apr-2016 to 10-apr-2016.
I have to calculate how many events are open for every day based on a selected date range.
Lets say if eventid 1 has got opened on 1st-APR and got closed on 10th-APR and I am calculating the number of opened issues for every day on 11th-APR then it should give me number of open event 1 from 1st-APR to 10th-APR.
Table Structure:-
================================================
EVENTID T1 T2
================================================
1 01-apr-2016 10-apr-2016
2 02-apr-2016 08-apr-2016
3 05-apr-2016 09-apr-2016
Expected Output:-
==============================================================================
DATE TOTAL_OPEN_EVENTS
==============================================================================
01-apr-2016 1
02-apr-2016 2(1 issue open on 1st(not closed on 2nd) and 1 on 2nd)
03-apr-2016 2
04-apr-2016 2
05-apr-2016 3
06-apr-2016 3
07-apr-2016 3
08-apr-2016 2(1 issue got closed on 8th(which was opened on 2nd))
09-apr-2016 2
10-apr-2016 0
How to do this kind of calculation in Oracle database ?
In order to generate the end report, you need a row for each date in your desired range. You could either use a calendar table, if available, or I find using a query on DUAL using CONNECT BY LEVEL < some_number works well to generate rows on the fly. (In this case "some_number" will be the number of days you want to report on.)
From there, you just need to join the individual dates to the date ranges in your event table:
-- create table "events" table
create table event_date_ranges
as
select 1 as event_id, TO_DATE('2016-APR-01', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-10', 'YYYY-MON-DD') as end_date from dual
union all
select 2 as event_id, TO_DATE('2016-APR-02', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-08', 'YYYY-MON-DD') as end_date from dual
union all
select 3 as event_id, TO_DATE('2016-APR-05', 'YYYY-MM-DD') as start_date, TO_DATE('2016-APR-09', 'YYYY-MON-DD') as end_date from dual
;
with
date_range_qry as
(-- one way to set the start and end dates for your report
select TO_DATE('2016-APR-01', 'YYYY-MM-DD') as report_start_date
, TO_DATE('2016-APR-10', 'YYYY-MM-DD') as report_end_date
from dual
)
, dates_qry
as
(
-- generate a row for all dates between 2016-APR-01 and 2016-APR-10
select report_start_date + ROWNUM - 1 as report_date
from dual
cross join
date_range_qry drq
connect by level <= (drq.report_end_date - drq.report_start_date + 1)
)
select dq.report_date, count(edr.event_id) as total_open_events
from dates_qry dq
left outer join
event_date_ranges edr
on dq.report_date >= edr.start_date
and dq.report_date < edr.end_date
group by dq.report_date
order by dq.report_date
Output:
REPORT_DATE TOTAL_OPEN_EVENTS
2016-APR-01 1
2016-APR-02 2
2016-APR-03 2
2016-APR-04 2
2016-APR-05 3
2016-APR-06 3
2016-APR-07 3
2016-APR-08 2
2016-APR-09 1
2016-APR-10 0
You can try this:
create table events_log
as
select 1 as event_id, TO_DATE('01-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('10-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 2 as event_id, TO_DATE('02-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('08-04-2016', 'DD/MM/YYYY') as T2 from dual
union all
select 3 as event_id, TO_DATE('05-04-2016', 'DD/MM/YYYY') as T1, TO_DATE('09-04-2016', 'DD/MM/YYYY') as T2 from dual
;
--------------
select v.REPORT_DATE, count(t.EVENT_ID) as open_event
from events_log t,
(select to_date('01/04/2016', 'DD/MM/YYYY') + ROWNUM - 1 as report_date
from dual
connect by level <= (to_date('11/04/2016', 'DD/MM/YYYY') -
to_date('01/04/2016', 'DD/MM/YYYY') + 1)) v
where t.T1(+) <= v.report_date
and t.T2(+) >= v.report_date
group by v.report_date
order by v.report_date;
Output will be:
report_date open_event
01/04/2016 1
02/04/2016 2
03/04/2016 2
04/04/2016 2
05/04/2016 3
06/04/2016 3
07/04/2016 3
08/04/2016 3
09/04/2016 2
10/04/2016 1
11/04/2016 0
I'm writing a query like this...
select to_char(e_date, 'MON/YYYY') as Month , location_code, count(employee_number) from...
Now I want to group by Month and Location_code. so how to use to_char(e_date, 'MON/YYYY') as Month in group by clause?
EDIT:
select to_char(vheda.e_date, 'MON/YYYY') as Months , hla.location_code, count(vheda.employee_number) emp_count from
virtu.virt_hr_emp_daily_attendance vheda
inner join per_all_people_f papf on vheda.party_id = papf.party_id
inner join per_all_assignments_f paaf on papf.person_id = paaf.person_id
inner join hr_locations_all hla on paaf.location_id = hla.location_id
where (trunc(sysdate) between PAPF.EFFECTIVE_START_DATE and PAPF.EFFECTIVE_END_DATE)
--and (vheda.e_in_time is not null)
and vheda.e_duration <> 0
and (trunc(sysdate) between PAAF.EFFECTIVE_START_DATE and PAAF.EFFECTIVE_END_DATE)
and vheda.e_date between '1-aug-2014' and '31-oct-2014'
group by hla.location_code, vheda.e_date
order by vheda.e_date
OUT PUT WHEN USE GROUP BY CLAUSE group by to_char(vheda.e_date, 'MON/YYYY'), hla.location_code:
ORA-00979: not a GROUP BY expression
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:
Error at Line: 58 Column: 37
select to_char(e_date, 'MON/YYYY') as Month , location_code, count(employee_number)
from ...
group by to_char(e_date, 'MON/YYYY'), location_code
You need to group by To_char(vheda.e_date, 'MON/YYYY') and hla.location_code.
SELECT To_char(vheda.e_date, 'MON/YYYY') AS Months,
hla.location_code,
Count(vheda.employee_number) emp_count
FROM virtu.virt_hr_emp_daily_attendance vheda
inner join per_all_people_f papf
ON vheda.party_id = papf.party_id
inner join per_all_assignments_f paaf
ON papf.person_id = paaf.person_id
inner join hr_locations_all hla
ON paaf.location_id = hla.location_id
WHERE ( Trunc(SYSDATE) BETWEEN PAPF.effective_start_date AND
PAPF.effective_end_date )
--and (vheda.e_in_time is not null)
AND vheda.e_duration <> 0
AND ( Trunc(SYSDATE) BETWEEN PAAF.effective_start_date AND
PAAF.effective_end_date )
AND vheda.e_date BETWEEN '1-aug-2014' AND '31-oct-2014'
GROUP BY To_char(vheda.e_date, 'MON/YYYY'),
hla.location_code
ORDER BY vheda.e_date
For example, let's see the same with EMP table,
SQL> SELECT To_char(hiredate, 'MON/YYYY') AS Months,
2 deptno,
3 Count(empno) emp_count
4 FROM emp
5 GROUP BY To_char(hiredate, 'MON/YYYY'),
6 deptno
7 /
MONTHS DEPTNO EMP_COUNT
-------- ---------- ----------
DEC/1980 20 1
JUN/1981 10 1
NOV/1981 10 1
MAY/1987 20 1
FEB/1981 30 2
MAY/1981 30 1
DEC/1981 30 1
JAN/1982 10 1
SEP/1981 30 2
DEC/1981 20 1
APR/1981 20 1
APR/1987 20 1
12 rows selected.
SQL>
select EXTRACT(MONTH FROM e_date)||'/'|| EXTRACT(Year FROM e_date) as months , location_code, count(employee_number)
FROM ...
group by EXTRACT(MONTH FROM e_date)||'/'|| EXTRACT(Year FROM e_date), location_code
You can also use EXTRACT function in GROUP BY clause..
i hope it helps..
My table contains pk_id,reviewer_id,rating.
There are 4 type of rating.
1-very good.
2-good.
3-bad.
4-very bad.
I want to calculate how much rating given by each reviewer.
Means:
If Akee having id 200 has given 2 very good,4 good,3 bad and zero very bad rating to different code.
I want result
count--- rate
2---------1
4---------2
3---------3
0---------4
My query is
SELECT COUNT(RATE),RATE
FROM CODE_REVIEW WHERE CODE_REVIEWER_ID= 200
GROUP BY RATE;
It is showing result
count--- rate
2---------1
4---------2
3---------3
I want to show the fourth row that is 4 rating zero.
How can it be done??
If Rate is not the primary key in another table then you need define your own list of rates so MySQL knows what the permutations of rate are:
SELECT Rates.Rate,
COUNT(Code_Review.Rate) AS CountOfRate
FROM ( SELECT 1 AS Rate UNION ALL
SELECT 2 AS Rate UNION ALL
SELECT 3 AS Rate UNION ALL
SELECT 4
) AS Rates
LEFT JOIN Code_Review
ON Code_Review.Rate = Rates.Rate
AND CODE_REVIEWER_ID = 200
GROUP BY Rates.Rate
Try this query:
SELECT coalesce(c.cnt, 0), r.rate
FROM (SELECT 1 AS rate UNION ALL SELECT 2
UNION ALL SELECT 3 UNION ALL SELECT 4) AS r
LEFT JOIN (SELECT COUNT(RATE),RATE
FROM CODE_REVIEW WHERE CODE_REVIEWER_ID= 200
GROUP BY RATE) AS c
ON r.rate = c.rate;
The first subquery creates a list of possible rates. You can avoid it if you have a table which defines all rates;
Second subquery is yours;
LEFT JOIN guarantees that all rates will be shown;
coalesce() is needed to convert NULL into 0.
Assuming that you do not have a separate table where the rates are defined.
SElECT * from (
SELECT distinct(m.rate), countrate from code_review m
LEFT JOIN
(SELECT COUNT(rate) as countrate,rate FROM code_review
WHERE code_reviewer_id=200 GROUP BY rate) t
ON m.rate=t.rate) a
You could do it somthing like this
SELECT
rates.RATE
, SUM(COUNT) COUNT
FROM
(
SELECT 1 RATE, 0 COUNT UNION ALL
SELECT 2 RATE, 0 COUNT UNION ALL
SELECT 3 RATE, 0 COUNT UNION ALL
SELECT 4 RATE, 0 COUNT
) Rates
LEFT JOIN
(
SELECT
RATE
, COUNT(RATE) COUNT
FROM
CODE_REVIEW
WHERE
CODE_REVIEWER_ID= 200
GROUP BY RATE
) Ratings200
ON Ratings200.RATE = Rates.RATE
If you can, you should push to try to get it in column format as it is simple as:
SELECT
SUM(rate = 1) AS 1,
SUM(rate = 2) AS 2,
SUM(rate = 3) AS 3,
SUM(rate = 4) AS 4
FROM
code_review
WHERE
code_reviewer_id = 200
But if you really need a row format, you could do:
SELECT
a.rate,
COUNT(b.rate) AS cnt
FROM
(
SELECT 1 AS rate UNION ALL
SELECT 2 AS rate UNION ALL
SELECT 3 AS rate UNION ALL
SELECT 4 AS rate
) a
LEFT JOIN
code_review b ON a.rate = b.rate AND code_reviewer_id = 200
GROUP BY
a.rate
SELECT
Rate,
totCount
FROM
(
Select
Rate,
count(Rate) as totCount
from
Code_Review
where
CODE_REVIEWER_ID = 200
group by
Rate
union
select 4, 0
union
select 3, 0
union
select 2, 0
union
select 1, 0
) AS T
group by
T.Rate