I want to fetch the data for sysdate-1 '00:00:00' between '23:59:59' time range. I have tried, but i am getting error.
This is my query..
select id_value, tn, LINE_TYPE_ID, ACCOUNT_TYPE_ID, PORT_ID, CURRENT_STATUS_ID, ERROR_CODE, ERROR_DESC, CRM_APP_CODE
from np_tn_dtls a
join np_port_req_dtls b on A.NP_TXN_ID=B.NP_TXN_ID
left join np_subscriber_dtls c on a.NP_TXN_ID=C.NP_TXN_ID
left join np_subscriber_id_dtls d on D.SUBSCRIBER_ID=C.SUBSCRIBER_ID
where (b.REQUEST_START_TIME between sysdate-1 '00:00:00'
AND sysdate '23:59:59') and (b.port_type_id != 2);
Please suggest me.
This expression is wrong:
between sysdate-1 '00:00:00'
AND sysdate '23:59:59'
Use trunc to round the date, so you can write this:
between trunc(sysdate-1) AND trunc(sysdate)
However, between is up to and including, so to prevent getting also request that happened exactly at midnight today, you can better write it like this:
b.REQUEST_START_TIME >= trunc(sysdate-1) AND
b.REQUEST_START_TIME < trunc(sysdate)
sysdate '23:59:59' is not a valid construction
use
b.REQUEST_START_TIME >= trunc(sysdate-1)
AND b.REQUEST_START_TIME < trunc(sysdate)
Related
i have a query
select count(1) z1
from sales_data
where ed_date >= sysdate -7
i need to group by ed
_date, remove the timestamp, and condition where ed_date is from 1/1/2021 to current sysdate
You can truncate the date:
select trunc(ed_date, 'DD') as ed_date, count(*) as z1
from sales_data
where ed_date >= date '2021-01-01'
and ed_date < trunc(sysdate, 'DD')
group by trunc(ed_date, 'DD')
The 'DD' truncation limit is the default so you could omit that, as just trunc(ed_date), if you prefer. Note though that it doesn't remove the time, it just sets it to midnight - an Oracle date always has both date and time components.
You can also order by trunc(ed_date), and in the select list you can format that however you want:
select to_char(trunc(ed_date), MM/DD/YYYY') as ed_date, count(*) as z1
from sales_data
where ed_date >= date '2021-01-01'
and ed_date < trunc(sysdate) -- to exclude today and future
-- and ed_date < trunc(sysdate) + 1 -- to include today but not tomorrow onwards
group by trunc(ed_date)
order by trunc(ed_date)
SELECT
subs_key,
sum(ROUNDED_DATA_VOLUME) AS RDV_SUM,
CASE WHEN to_char(CALL_START_TIME , 'HH24:MI:SS') >= '00:00:00'
AND to_char(CALL_START_TIME , 'HH24:MI:SS') <= '07:00:00' THEN 'Night'
WHEN to_char(CALL_START_TIME , 'HH24:MI:SS') > '07:00:00'
AND to_char(CALL_START_TIME , 'HH24:MI:SS') <= '23:59:59' THEN 'Day'
END AS Tariff_flag
FROM DWH.FCT_USAGE_PREP_OGPRS_N
WHERE CALL_START_TIME >= to_date('2021-11-01', 'YYYY-MM-DD')
AND CALL_START_TIME <= to_date('2021-11-30', 'YYYY-MM-DD')
GROUP BY
SUBS_KEY,
CASE WHEN (to_char(CALL_START_TIME , 'HH24:MI:SS') >= '00:00:00'
AND to_char(CALL_START_TIME, 'HH24:MI:SS') <= '07:00:00') THEN 'Night'
WHEN (to_char(CALL_START_TIME , 'HH24:MI:SS') > '07:00:00'
AND to_char(CALL_START_TIME, 'HH24:MI:SS') <= '23:59:59') THEN 'Day'
END
My query takes more than hour and still running. Is there any way to optimize it?
UPD:
Execution Plan
Is that what Ankit asked?
You are grouping by a relatively complex function:
CASE WHEN (to_char(CALL_START_TIME , 'HH24:MI:SS') >= '00:00:00' AND to_char(CALL_START_TIME , 'HH24:MI:SS') <= '07:00:00') THEN 'Night'
WHEN (to_char(CALL_START_TIME , 'HH24:MI:SS') > '07:00:00' AND to_char(CALL_START_TIME , 'HH24:MI:SS') <= '23:59:59') THEN 'Day' END
If this particular query is important enough you could index this whole thing, but I suspect you would be better off getting the hour using extract.
CASE WHEN extract(hour from CALL_START_TIME) > 7 then 'Night' --midnight (inclusive) - 7am (exclusive)
else 'Day' --7am (inclusive) - midnight (exclusive)
END
For your where clause I would
I have no way to tell whether this will speed up your query. Or speed it up sufficiently for your use case. But you can try out the two queries and see if one of them is significantly faster than the other. Also, if you're frequently using times, it might make sense to index extract(hour from CALL_START_TIME), whereas an index on your entire case statement is only likely to get used in this one query.
Your question is how to speed up the query but when I have a query that takes hours to run I will often not bother to optimize it. It's long enough that you're unlikely to get the kind of speed-ups you need to have an application executing the query based on a user's request, and if a query takes 1 hour or 12, you likely need to plan when you run it.
I have a question regarding getting yesterday's data in oracle sql
my query is something like this:
SELECT
SUM(CURRENT_WEIGHT)
FROM
FABRICATION_HIST
WHERE
FAB_ENTRY_DATE = TO_DATE(SYSDATE-1, 'MM/DD/YYYY')
The value in FAB_ENTRY_DATE is like this:
8/25/2014 3:03:11 PM
And it doesn't show any data when I execute the query, Please help me
SELECT
SUM(CURRENT_WEIGHT)
FROM
FABRICATION_HIST
WHERE
to_date(FAB_ENTRY_DATE, 'MM/DD/YYYY') = TO_DATE(SYSDATE-1, 'MM/DD/YYYY')
[You should match only the date part]
or
SELECT
SUM(CURRENT_WEIGHT)
FROM
FABRICATION_HIST
WHERE
FAB_ENTRY_DATE >= (SYSDATE - 1) and FAB_ENTRY_DATE < SYSDATE;
More efficient (if FAB_ENTRY_DATE has index - uses it):
SELECT SUM(CURRENT_WEIGHT)
FROM FABRICATION_HIST
WHERE FAB_ENTRY_DATE >= TRUNC(SYSDATE)-1
AND FAB_ENTRY_DATE < TRUNC(SYSDATE)
NOTE:
Don't use TO_DATE(SYSDATE, 'MM/DD/YYYY') to drop time part:
as it works only if default date format on database is 'MM/DD/YYYY', if not - you get errors like this:
ORA-01843: not a valid month : SELECT TO_DATE(SYSDATE, 'MM/DD/YYYY') FROM DUAL
You have equality. 8/25/2014 3:03:11 PM won't be equal to 8/25/2014
You need to specify a range:
WHERE FAB_ENTRY_DATE >= TO_DATE(SYSDATE-1, 'MM/DD/YYYY')
AND FAB_ENTRY_DATE < TO_DATE(SYSDATE, 'MM/DD/YYYY')
Try this:
SELECT
SUM(CURRENT_WEIGHT)
FROM
FABRICATION_HIST
WHERE
TO_CHAR(FAB_ENTRY_DATE, 'MM/DD/YYYY') = TO_CHAR(SYSDATE-1, 'MM/DD/YYYY')
Since you don't need to get the sum on a span of dates (between two dates), you can compare the date that you want as varchar without the Time portion. "8/25/2014" = "8/25/2014"
you can trunc data column:
SELECT
SUM(CURRENT_WEIGHT)
FROM
FABRICATION_HIST
WHERE
to_date(FAB_ENTRY_DATE, 'MM/DD/YYYY') = trunc(SYSDATE) - 1
see Oracle's documentation
How can I retrieve data on time range where tickets issued between the times of 6am - 9:15am for the past month.
I tried this but was wrong.Its in oracle and to_char is not function name in SQL. how can i do that in sql.
select *
from [ICPS].[dbo].[tickets]
where t_date_time_issued > sysdate - 30
and to_char(t_date_time_issed, 'hh24:mi:ss') >= '06:00:00'
and to_char(t_date_time_issued, 'hh24:mi:ss') <= '09:15:00'
Assuming that you want it in SQL-Server("Its in oracle and to_char is not function name in SQL"), you can cast the datetme to time:
SELECT *
FROM [dbo].[tickets]
WHERE t_date_time_issued > DATEADD(mm, - 30, GetDate())
AND Cast(t_date_time_issued as TIME) between '06:00' and '09:10'
Demo
You can use to_timestamp() in stead of to_char. Details about to_timestamp() is: http://docs.oracle.com/cd/B28359_01/olap.111/b28126/dml_functions_2118.htm#OLADM696
Hope will help!
try this:
SELECT
*
FROM
[ICPS].[DBO].[tickets]
WHERE
t_date_time_issued BETWEEN add_months(TRUNC(SYSDATE, 'MM'), - 1) AND (
TRUNC(SYSDATE, 'MM') - (1/24/60/60))
AND TO_CHAR(t_date_time_issed, 'HH24:MI:SS') >= '06:00:00'
AND TO_CHAR(t_date_time_issed, 'HH24:MI:SS') <= '09:15:00'
SELECT *
FROM [ICPS].[dbo].[tickets]
WHERE convert (datetime,t_date_time_issued,101)
between convert(datetime,'2013/11/01',101) and convert (datetime,'2013/12/04',101)
AND datepart(hour,t_date_time_issued) between '06' and '09'
I keep getting an error 'ORA-00905: missing keyword' with the following statement, ever since I introduced the CASE statement, but I can't figure out what is missing.
SELECT
CYCLE_S_FACT_MAIN.STARTTIME,
CYCLE_S_FACT_MAIN.ENDTIME
FROM
CYCLE_S_FACT_MAIN
WHERE
(
CYCLE_S_FACT_MAIN.ENDTIME >
(SELECT SYSDATE,
CASE SYSDATE
WHEN TO_CHAR(SYSDATE, 'HH') < 6 THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END AS SYSDATE
FROM DUAL
)
AND
CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
)
You're mixing up the two forms of CASE expressions. There's a simple expression (when you're just wanting to compare expressions for equality):
CASE Expr1
WHEN Expr2 THEN ...
WHEN Expr3 THEN ...
ELSE ...
END
And there's a searched CASE expression, where you want to evaluate separate predicates:
CASE
WHEN Predicate1 THEN ...
WHEN Predicate2 THEN ...
ELSE ...
END
For a searched CASE, you don't specify an expression between CASE and the first WHEN.
Damien_The_Unbeliever is right about mixing case styles, but you also don't need the subquery at all, and the one you have is getting two columns back - which you can't compare with a single value. You can just do this:
WHERE
CYCLE_S_FACT_MAIN.ENDTIME > CASE
WHEN TO_NUMBER(TO_CHAR(SYSDATE, 'HH24')) < 6
THEN TRUNC(SYSDATE) + INTERVAL '6' HOUR
ELSE TRUNC(SYSDATE) - INTERVAL '1' DAY + INTERVAL '6' HOUR END
AND CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
This leaves the comparison as between two dates, rather than relying on implcit conversions. I've also used HH24; using HH would treat times between midday and 6pm the same as those between midnight and 6am, which I'm prety sure you didn't intend.
Try as
SELECT
CYCLE_S_FACT_MAIN.STARTTIME,
CYCLE_S_FACT_MAIN.ENDTIME
FROM
CYCLE_S_FACT_MAIN
WHERE
(
CYCLE_S_FACT_MAIN.ENDTIME >
(SELECT SYSDATE,
CASE
WHEN TO_CHAR(SYSDATE, 'HH') < 6 THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END AS "MY_SYSDATE"
FROM DUAL
)
AND
CYCLE_S_FACT_MAIN.ENDTIME <= SYSDATE
)
There two possible mistakes, one is it is expecting as CASE WHEN not as CASE sysdate WHEN and second one is sysdate as alias which is not possible to use as alias name.
SELECT TO_CHAR(SYSDATE,'HH'),
CASE
WHEN TO_CHAR(SYSDATE,'HH') < 6
THEN CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
ELSE CONCAT(TO_CHAR(SYSDATE - INTERVAL '1' DAY, 'DD-MM-YYYY'), ' 06:00:00')
END "sysdate" ,
TO_CHAR(SYSDATE, 'HH'),
CONCAT(TO_CHAR(SYSDATE, 'DD-MM-YYYY'), ' 06:00:00')
FROM dual;
12 24-07-2013 06:00:00 12 25-07-2013 06:00:00