I want to compare sales months with the system month. if equal get 1 output as new column(last_month) else 0. I tried below oracle query but I am getting a Null value.
SELECT a.agent_id,a.agent_name,a.ivr_registered_district,s.agent_type,s.district,s.province,a.parent_level1_id,a.parent_level1,a.sales_channel,TO_CHAR(TRUNC(a.connection_date, 'MONTH'), 'MON-YYYY') AS MONTHYEAR,
CASE
WHEN TO_CHAR(TRUNC(a.connection_date, 'MONTH'), 'MON-YYYY') = TO_CHAR(ADD_MONTHS(SYSDATE, - 1))
THEN 1
END as last_month
FROM EDW_TGT.FACT_LTE_SALES_CHANNELS a
JOIN SFA.sfa_agent_dtl s
ON a.agent_id = s.agent_id
where a.pre_post = 'LTE-PREPAID' and a.sales_channel in ('BUSINESS PARTNER', 'INSTITUSIONAL', 'REGIONAL TRADE PARTNERS', 'DISTRIBUTOR')
and a.connection_date >= TO_DATE('2020-01-01 00:00:0', 'YYYY-MM-DD HH24:MI:SS')
You don't need to truncate date as oracle provides you functionality to extract (day,month,year) from to_date function.
Your query should be like below.
SELECT a.agent_id,a.agent_name,a.ivr_registered_district,s.agent_type,s.district,s.province,a.parent_level1_id,a.parent_level1,a.sales_channel,TO_CHAR(TRUNC(a.connection_date, 'MONTH'), 'MON-YYYY') AS MONTHYEAR,
CASE
WHEN to_char(to_date(a.connection_date, 'DD-MM-YYYY'), 'Month') = to_char(to_date(sysdate-1, 'DD-MM-YYYY'), 'Month')
THEN 1
Else 0
END as last_month
FROM EDW_TGT.FACT_LTE_SALES_CHANNELS a
JOIN SFA.sfa_agent_dtl s
ON a.agent_id = s.agent_id
where a.pre_post = 'LTE-PREPAID' and a.sales_channel in ('BUSINESS PARTNER', 'INSTITUSIONAL', 'REGIONAL TRADE PARTNERS', 'DISTRIBUTOR')
and a.connection_date >= TO_DATE('2020-01-01 00:00:0', 'YYYY-MM-DD HH24:MI:SS')
Related
Error comes on AS LastYearVolumeBilled this line how to add two case when in one select statement
select 'R-1' as Year,
(case when SDBM_MONTH_YR = to_number(extract(year from sysdate) || '04')then
round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
end )AS CurrentYearVolumeBilled
FROM t_servicedetail_billing
where SDBM_MONTH_YR= to_number(extract(year from sysdate) || '04')
group by SDBM_MONTH_YR ,
(CASE WHEN SDBM_MONTH_YR = to_number( extract(year from add_months(sysdate,-12)) || '04')
THEN round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
END)AS LastYearVolumeBilled
FROM t_servicedetail_billing
where SDBM_MONTH_YR= to_number( extract(year from add_months(sysdate,-12)) || '04')
group by SDBM_MONTH_YR;
These are two different queries, so one option might be to treat them as such by using a CTE (as my example shows) or as subqueries.
WITH
t_curr
AS
( SELECT 'R-1' AS year,
(CASE
WHEN sdbm_month_yr =
TO_NUMBER (EXTRACT (YEAR FROM SYSDATE) || '04')
THEN
ROUND (
(SUM (sdbm_billed_units) / AVG (sdbm_billing_days))
/ 1000,
2)
END) AS currentyearvolumebilled
FROM t_servicedetail_billing
WHERE sdbm_month_yr = TO_NUMBER (EXTRACT (YEAR FROM SYSDATE) || '04')
GROUP BY sdbm_month_yr),
t_last
AS
( SELECT 'R-1' AS year,
(CASE
WHEN sdbm_month_yr =
TO_NUMBER (
EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -12))
|| '04')
THEN
ROUND (
(SUM (sdbm_billed_units) / AVG (sdbm_billing_days))
/ 1000,
2)
END) AS lastyearvolumebilled
FROM t_servicedetail_billing
WHERE sdbm_month_yr =
TO_NUMBER (
EXTRACT (YEAR FROM ADD_MONTHS (SYSDATE, -12)) || '04')
GROUP BY sdbm_month_yr)
SELECT a.year, a.currentyearvolumebilled, b.lastyearvolumebilled
FROM t_curr a CROSS JOIN t_last b;
How to add more subqueries (simplified):
with
t_curr_r1 as
(select 'R-1' as year, ... from ...),
t_curr_r2 as
(select 'R-2' as year, ... from ...),
t_curr_r3 as
(select 'R-3' as year, ... from ...),
--
t_last_r1
(select 'R-1' as year, ... from ...),
t_last_r2 as
(select 'R-2' as year, ... from ...),
t_last_r3 as
(select 'R-3' as year, ... from ...),
--
select c1.year, c1.currentyearvolumebilled,
c2.currentyearvolumebilled,
c3.currentyearvolumebilled,
...
l1.lastyearvolumebilled,
l2.lastyearvolumebilled,
l3.lastyearvolumebilled,
...
from t_curr_r1 c1 cross join t_curr_r2 c2
cross join t_curr_r3 c3
...
cross join t_last_r1 l1
cross join t_last_r2 l2
cross join t_last_r3 l3
...
You have repeated your query twice. You don't need a case statement cause you have the same condition in where clause. So the correct query might be -
select 'R-1' as Year,
round((sum(SDBM_BILLED_UNITS)/avg(sdbm_billing_days))/1000,2)
END AS CurrentYearVolumeBilled
FROM t_servicedetail_billing
WHERE SDBM_MONTH_YR = to_number(extract(year from sysdate) || '04')
I'm trying to query my Oracle script on Toad but got slow response, about 4-8 seconds.
The script query is about count, below is mine:
SELECT COUNT(*)
AS TOTALS
FROM(SELECT S.BADGEID_FK, S.SHIFT, S.STATUS, E.BADGEID, E.FIRSTNAME, E.LASTNAME
FROM WA_SEW_TBL_EMP_INFO S, WA_GA_TBL_EMPLOYEES E
WHERE S.BADGEID_FK = E.BADGEID AND S.STATUS = 'Attend' AND S.SHIFT = 'Morning'
AND S.BADGEID_FK NOT IN(SELECT EMPID
FROM WA_SEW_TBL_RESULTS
WHERE TO_CHAR(SYSTEM_DATE, 'YYYY-MM-DD') = '2017-08-30'
AND TO_CHAR(SYSTEM_DATE, 'HH24:MI') >= '07:00'
AND TO_CHAR(SYSTEM_DATE, 'HH24:MI') <= '19:29'))
I tried to add indexing to some column, but there is no effect.
Is there any way to do that query? or any trick?
This part:
WHERE TO_CHAR(SYSTEM_DATE, 'YYYY-MM-DD') = '2017-08-30'
AND TO_CHAR(SYSTEM_DATE, 'HH24:MI') >= '07:00'
AND TO_CHAR(SYSTEM_DATE, 'HH24:MI') <= '19:29'
Would be better rewritten as:
WHERE SYSTEM_DATE between to_date ('2017-08-30 07:00:00', 'YYYY-MM-DD HH24:MI:SS')
and to_date ('2017-08-30 19:29:59', 'YYYY-MM-DD HH24:MI:SS')
That will allow any index on SYSTEM_DATE to be used.
One obvious suspect is your date manipulation in the IN list. You should never, ever use functions around dates - that kills any ability of Oracle to use an index on the date column.
Instead:
where system_date >= to_date('2017-08-30 07:00', 'yyyy-mm-dd hh24:mi')
and system_date < to_date('2017-08-30 19:30', 'yyyy-mm-dd hh24:mi')
(the second inequality is strict, if you want to exclude 7:30pm sharp).
I was able to eliminate most of the subqueries but I'm not sure it will result in the performance gain w/o knowledge of table size and indexes. Posting the execution plan would help us understand where your bottleneck is.
SELECT count(*) as Totals
FROM WA_SEW_TBL_EMP_INFO S
INNER JOIN WA_GA_TBL_EMPLOYEES E
ON S.BADGEID_FK = E.BADGEID
LEFT JOIN WA_SEW_TBL_RESULTS R
ON S.BADGEID_FK =R.EMPID
-- Others already addressed what needs to happen here.
AND TO_CHAR(R.SYSTEM_DATE, 'YYYY-MM-DD') = '2017-08-30'
AND TO_CHAR(R.SYSTEM_DATE,'HH24:MI') >= '07:00'
AND TO_CHAR(R.SYSTEM_DATE,'HH24:MI') <= '19:29'
WHERE S.STATUS = 'Attend'
AND S.SHIFT = 'Morning'
AND R.EmpID is null
Trying to automate a query that will pull data for the current month where the day of the month (in the date field) is >= the 15th. Is this possible? If so, what is the syntax to achieve this?
I want to be able to run this query each month without having to change anything. So in May, it would automatically pull any item where the date was >= 5/15/16. In June, it would pull items where the date was >= 6/15/16. And so on.....
Any help in this would be greatly appreciated. Thanks
This will allow you to use any indexes you have on your date_field column:
SELECT *
FROM table_name
WHERE date_field >= TRUNC( SYSDATE, 'MM' ) + INTERVAL '14' DAY
AND date_field < ADD_MONTHS( TRUNC( SYSDATE, 'MM' ), 1 );
If your date/time fields are of type timestamp you can do
select x from <your_table>
where EXTRACT(DAY from <timestamp field>) >=15
and EXTRACT(MONTH from <timestamp field>) = EXTRACT(MONTH FROM CURRENT_TIMESTAMP)
and EXTRACT(YEAR from <timestamp field>) = EXTRACT(YEAR FROM CURRENT_TIMESTAMP);
I think what you're after is something like:
with sample_data as (select 1 id, to_date('01/06/2016', 'dd/mm/yyyy') dt from dual union all
select 2 id, to_date('10/06/2016', 'dd/mm/yyyy') dt from dual union all
select 3 id, to_date('14/06/2016', 'dd/mm/yyyy') dt from dual union all
select 4 id, to_date('15/06/2016', 'dd/mm/yyyy') dt from dual union all
select 5 id, to_date('16/06/2016', 'dd/mm/yyyy') dt from dual union all
select 6 id, to_date('30/06/2016', 'dd/mm/yyyy') dt from dual union all
select 7 id, to_date('01/07/2016', 'dd/mm/yyyy') dt from dual)
select *
from sample_data
where dt >= trunc(sysdate, 'mm') + 14
and dt < last_day(trunc(sysdate)) + 1;
ID DT
---------- ----------
4 15/06/2016
5 16/06/2016
6 30/06/2016
(If you wanted rows with any date greater than the 15th of the current month, then remove the last predicate in the where clause.)
I am trying to extract rows from a table to gain the start and end time for events, these are held in a one to many table relationship so that for each instanceid in the master table you can have a number of entryids in the child. I have successfully written the below query that extracts the required data converting epoch timestamps, but am getting rows with NULL values. I can see that to exclude these I need to only select rows from table_a where the status value reflect 1 or 6, but am not sure of syntax for achieving this, I have tried combos of bold highlighted line below to no avail.
SELECT a.summary
to_char(date '1970-01-01' + b.create_date/86400, 'DD Mon YYYY HH24:MI:SS') as start_date,
to_char(date '1970-01-01' + c.create_date/86400, 'DD Mon YYYY HH24:MI:SS') as completed_date,
to_char (TRUNC (SYSDATE) + NUMTODSINTERVAL ((c.create_date - b.create_date), 'second'), 'hh24:mi:ss') as Elapse_Time,
a.status
FROM o2_hpov_casecreation a
LEFT OUTER JOIN o2_hpov_casecreation_audit b
ON (a.instanceid = c.entryid
AND B.action= 'Queueing Simulation phase on SYS:Action')
LEFT OUTER JOIN o2_hpov_casecreation_audit c
ON (a.instanceid = c.entryid
AND c.action = 'Notifications completed')
AND a.status IN (2,6)
You need to add your filter criteria to the where clause
below is a corrected version of your query
SELECT a.summary
to_char(date '1970-01-01' + b.create_date/86400, 'DD Mon YYYY HH24:MI:SS') as start_date,
to_char(date '1970-01-01' + c.create_date/86400, 'DD Mon YYYY HH24:MI:SS') as completed_date,
to_char (TRUNC (SYSDATE) + NUMTODSINTERVAL ((c.create_date - b.create_date), 'second'), 'hh24:mi:ss') as Elapse_Time,
a.status
FROM o2_hpov_casecreation a
LEFT OUTER JOIN o2_hpov_casecreation_audit b
ON (a.instanceid = c.entryid
AND B.action= 'Queueing Simulation phase on SYS:Action')
LEFT OUTER JOIN o2_hpov_casecreation_audit c
ON (a.instanceid = c.entryid
AND c.action = 'Notifications completed')
WHERE a.status IN (2,6)
This question already has answers here:
Number of fridays between two dates
(7 answers)
Closed 8 years ago.
I have two parameters(start_Date,end_Date) from table1
I'm trying to count no of saturdays and sundays in a date range
star_Date=8/20/2014 13:52
end_Date=8/28/2014 13:52
And result should be like this
Start_Date end_date No_of_leaves
8/20/2014 13:52 8/28/2014 13:52 2
Update Section
SELECT retouch_req_time,retouch_submit_time,(
SELECT Count(*) FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM (WITH t AS (SELECT To_date (retouch_req_time, 'MM/DD/YYYY HH24:MI') start_date, To_date (retouch_submit_time, 'MM/DD/YYYY HH24:MI') end_date FROM TT))
CONNECT BY LEVEL <= end_date - start_date + 1) WHERE dt IN ('friday','saturday')) as worked_hours
FROM TT
You can try using hierarchical queries
WITH t
AS (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI') start_date,
To_date ('8/28/2014 13:52', 'MM/DD/YYYY HH24:MI') end_date
FROM dual)
SELECT Count(*)
FROM (SELECT To_char(start_date + ( LEVEL - 1 ), 'fmday') dt
FROM t
CONNECT BY LEVEL <= end_date - start_date + 1)
WHERE dt IN ( 'friday', 'saturday' );
RESULT
------
2
* The dates are listed by expanding the range.
* The TO_CHAR function is used to obtain the weekday
* Count everthing which is a friday or saturday
If you want to find the day wise count, then you can try
SELECT To_char(dat, 'DY'),
Count(*)
FROM (SELECT To_date ('8/20/2014 13:52', 'MM/DD/YYYY HH24:MI')
+ num dat
FROM (SELECT LEVEL - 1 num
FROM dual
CONNECT BY LEVEL <= Abs(To_date ('8/20/2014 13:52',
'MM/DD/YYYY HH24:MI') -
To_date (
'8/28/2014 13:52'
,
'MM/DD/YYYY HH24:MI')) - 1
))
WHERE To_char(dat, 'DY') IN ( 'FRI', 'SAT' )
GROUP BY To_char(dat, 'DY');
RESULTS
TO_CHAR(DAT,'DY') COUNT(*)
----------------- --------
FRI 1
SAT 1
You can calculate the number of saturdays and sundays like this:
with t(d) as (
select sysdate + level from dual connect by rownum < 10
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t
CNT
---
2
If you don't have a range of dates then:
with t(a, b) as (
select sysdate a, sysdate + 10 b from dual connect by rownum < 10
), t2(d) as (
select a + level - 1 from t connect by rownum <= b - a
)
select count(case when trim(to_char(d, 'DAY')) in ('SATURDAY', 'SUNDAY') then 1 end) cnt from t2
CNT
---
2