SQL Command not properly ended ( oracle 11g for windows) - sql

I m using this query to get a result of the difference between the start time and end time of an activity. Where the end time is null i wanted to put the minimum value as 500. Please advice and HELP!!
select * from table
where (end_time - start_time) * 24 * 60 > 1,
IF end_time IS NULL THEN '500';

So this is your query:
select * from table where (end_time - start_time) * 24 * 60 > 1;
But you want to treat a null end_time as 500. So use NVL or COALESCE to replace the null with 500:
select * from table where (nvl(end_time,500) - start_time) * 24 * 60 > 1;

IF end_time IS NULL THEN '500';
Just to make it more clear, '500' is not a number rather a string since it is enclosed within single quotation marks.
Now, end_time is. DATE data type or a timestamp, ideally. So, 500 makes no sense. You must convert it to appropriate type, whether 500 is days, hours, minutes, seconds, fraction of a second.
As in other answer it is suggested to use NVL(end_time, 500), it makes no sense. What does 500 - a date mean? Applying NVL is the need, however, you must convert it to the required value, else those are two different data types and Oracle won't allow it.
UPDATE
In my opinion,
Difference between two dates gives the number of days to the precision of seconds converted back to days. But, difference between an arbitrary number and a date makes no sense.

I assumed that start_time and end_time columns have number as datatype, for this calculation you need to select these specific columns and not all (*). Comparison is in where clause, this works in oracle11.
select ((NVL(END_TIME, 500)-START_TIME) * 24 * 60) from TABLE_NAME where ((NVL(END_TIME, 500)-START_TIME) * 24 * 60) > 1;

Related

Return DATEDIFF in milliseconds on SQL Server 2008R2

I have a SQL query returning a value for x, which is a timestamp, mapped to a C# object of type long:
SELECT DATEDIFF(second, { d '1970-01-01'}, dateCompleted) AS x
The above statement works. However, I need to get the timestamp to return the value in milliseconds rather than seconds. In SQL Server 2016 I can do this:
SELECT DATEDIFF_BIG(millisecond, { d '1970-01-01'}, dateCompleted) AS x
...and that works great. However, I'm stuck on SQL Server 2008 R2.
I could return the values and do some post-processing in C# to multiply x by 1000 but I wondered if there's a way to handle this in the query itself. I've tried a simple multiplication but that yields an Arithmetic overflow error:
SELECT DATEDIFF(second, { d '1970-01-01'}, dateCompleted) * 1000 AS x
Could anyone suggest how to accomplish this?
Thanks.
DATEDIFF returns an INT so it cannot be used to return difference in millisecond if the two dates are far (approx. 25 days) apart. However you could calculate the difference in seconds, BIGINT multiply by 1000, and add the milliseconds:
SELECT DATEDIFF(SECOND, '1970-01-01', dateCompleted)
* CAST(1000 AS BIGINT)
+ DATEPART(MILLISECOND, dateCompleted)
Assuming you want UNIX timestamp you also need to add the timezone offset to the result (I hope you stored it along with date completed).
How about using cast() or convert()?
SELECT DATEDIFF(second,{ d '1970-01-01'},dateCompleted) * convert(bigint, 1000) AS x
Perhaps a variable?
DECLARE #milli BIGINT;
SET #milli = DATEDIFF(second,{ d '1970-01-01'},dateCompleted) * 1000.0;
SELECT #milli;
Datediff return int value so second will have issue with int data type.
you can get the minutes or days and multiple with 60 for getting seconds
SELECT DATEDIFF(m,{ d '1970-01-01'},getdate()) * 1000 * 60

TIme - SQL (Minutes and Seconds)

I created a TIME table. This table has two columns: one for minutes and another one for seconds. I made their datatype as a Decimal.
Is there a way to create a derivative column where minutes and seconds are in this format mm:ss from my two columns?
IF NOT, How do I insert data into my minute column if its not a DECIMAL type? What type should it be?
Thank you!
Note I am using SQL server
Your comments make it sound like you're trying to do arithmetic on intervals (or durations).
SQL Server's time data type "Defines a time of a day. The time is without time zone awareness and is based on a 24-hour clock." You can't add two time values; 2 o'clock + 3 o'clock is literally nonsense. In SQL Server 2012 . . .
select cast('2:00' as time) + cast('3:00' as time)
Operand data type time is invalid for add operator.
Other dbms might return a nonsensical number.
Standard SQL includes a data type called interval, which supports the arithmetic and formatting you'd expect. So 2 o'clock + 3 hours would return 5:00:00 (5 o'clock). In the absence of support for the interval data type, store the most granular unit (seconds, for you) as an integer, and format it yourself for display. I might use a view, myself.
declare #val as integer;
-- 10:01:12, 10 hours, 1 minute, 12 seconds, in seconds.
set #val = (10 * 60 * 60) + (1 * 60) + 12;
-- Leading zeroes for minutes and seconds.
select #val as total_sec,
concat(#val / (60 * 60), ':', format((#val / 60) % 60, 'D2'), ':', format(#val % 60, 'D2')) as total_time
total_sec total_time
--
36072 10:01:12
As #mclaassen pointed out, I'd be curious why you aren't using the built in time data type.
That said, if you really want to build a time table by hand, then you can have a calculated column. Let's call it timeString.
alter table [time]
add timeString as (left('0' + cast([minutes] as varchar(10)), 2) + ':' + left('0' + cast([seconds] as varchar(10)), 2))
See https://msdn.microsoft.com/en-us/library/ms188300.aspx for documentation on calculated columns in SQL Server.

Oracle sql: ORA-01830 when date calculation happens

I want to perform following oracle SQL query
SELECT t1.Technology, count(t1.trax_id) as "Current number of items", to_char(to_date(max(round((SYSDATE - t1.time_event) * 24 * 60 * 60)),'sssss'),'hh24:mi:ss') as "max_ages"
from dm_procmon t1
group by t1.Technology;
The problem is the date substration formula.
I susbtract 2 dates from each other. This gives me a decimal value
(like 0,00855605). I want the value back to be a date value. So I
converted this first to a Number (Decimal > Number) and than to a
char (Number > Char) Finally from a char to date (Char > Date).
But when I perform the action I receive
Error report -
SQL Error: ORA-01830: Datumnotatieafbeelding eindigt voordat de gehele
invoerstring is geconverteerd.
01830. 00000 - "date format picture ends before converting entire input string"
What do I do wrong?
you try to convert to_date(%number of seconds%, 'sssss'), that is the problem. just use TO_CHAR(MAX(TO_DATE('20000101','yyyymmdd')+(SYSDATE - t1.time_event)),'hh24:mi:ss'); this will function correctly for intervals < 1day
here is a general solution without any limitations on maximum interval size:
select Technology, cnt as "Current number of items", FLOOR(x) || ':' || TO_CHAR(TO_DATE('20000101','yyyymmdd')+(x - FLOOR(x)),'hh24:mi:ss') as "max_ages"
from
(select t1.Technology, COUNT(t1.trax_id) cnt, MAX(SYSDATE - t1.time_event) x
from dm_procmon t1
group by t1.Technology);
FLOOR(x) returns the days and the rest (x - FLOOR(x)) is added to a constant date and transformed to hours, minutes and seconds
The following will give a DAY TO SECOND INTERVAL for all dates within about 68 years of one another:
SELECT t1.technology, COUNT(t1.trax_id) AS "Current number of items"
, NUMTODSINTERVAL(ROUND((SYSDATE - MIN(t1.time_event) * 24 * 60 * 60), 'SECOND') AS "max_ages"
FROM dm_procmon t1
GROUP BY t1.technology;
Note that rather that using MAX(SYSDATE - time), I used SYSDATE-MIN(time) (logically the same). The advantage of using this instead of TO_CHAR() is that you can then use the value returned in DATE/INTERVAL arithmetic.

How to filter SQL by time (greater and less than)?

I want to query a subset from a dataset. Each row has a time stamp of the following format:
2014-04-25T17:25:14
2014-04-25T18:40:16
2014-04-25T18:44:57
2014-04-25T19:10:32
2014-04-25T20:22:12
...
Currently, I use the following query to select a time-based subset:
time LIKE '%2014-04-25T18%' OR time LIKE '%2014-04-25T19%'
This becomes quite complicated when you start to filter by mintutes or seconds.
Is there a way to run a query that such as ...
time > '%2014-04-25T18%' AND time < '%2014-04-25T19%'
A regular expression would be okay, too.
The database is a SpatiaLite database. The time column is of type VARCHAR.
If the date is being treated as a string and based on the example above:
time LIKE '%2014-04-25T18%' AND time <> '%2014-04-25T18:00:00:000'
Otherwise, you could convert the date to seconds since midnight and add 60 minutes to that to create the range part of the filter
DECLARE #test DATETIME = '2014-04-25T17:25:14'
SELECT #test
, CONVERT(DATE,#test) AS JustDate
, DATEDIFF(s,CONVERT(DATETIME,(CONVERT(DATE,#test))), #test) AS SecondsSinceMidnight
-- 60 seconds * 60 minutes * 24 hours = 86400
Thanks to your posts and this answer I came up with this solution:
SELECT * FROM data
WHERE DATETIME(
substr(time,1,4)||'-'||
substr(time,6,2)||'-'||
substr(time,9,2)||' '||
substr(time,12,8)
)
BETWEEN DATETIME('2014-04-25 18:00:00') AND DATETIME('2014-04-25 19:00:00');

Division of dates to create percentage SQL

I am trying to do write in a function to subtract a few dates, then divide them together, add 1 then * 100 to get an overall % complete.
((SYSDATETIME() - proj.proj_scheduledDate)/(proj.proj_dueDate - proj.proj_scheduledDate + 1)) * 100 as 'percent done
returns
Operand data type datetime is invalid for divide operator.
What do I need to do to get this query to work? THANKS!
Might I suggest using DATEDIFF() with dd for a day datepart -- you can easily get the percentage of days completed - or go to smaller datepart values if you need to.
Returns the count (signed integer) of the specified datepart
boundaries crossed between the specified startdate and enddate.
SELECT
FLOOR((DATEDIFF(NOW(), proj.proj_scheduledDate) / DATEDIFF(proj.proj_dueDate, proj.proj_scheduledDate)) * 100)
FROM
foo;