I have a set analysis and need to restrict the range of the maxmim date to -1 -
=max({<BREAK={'5Days'}>}date(DATE))
I tried like this but I have an error -
=max({<BREAK={'5Days'}, DATE = {Today()-1}>}date(DATE)) and
=max({<BREAK={'5Days'}>+< DATE = {Today()-1}>}date(DATE))
Do you have any other idea?
I solved it like this -
=max({<BREAK={'5Days'}>}date((DATE)-1))
and it worked perfectly. In fact it gave the maximum date - 1.
Related
I'm trying to make 3 separate fields from a date and now I ran into this problem. When the (DDMMYYYY European style) date is like 04032017, the code:
SELECT SUBSTRING(CAST(04032017 AS VARCHAR(38)), 2, 2) AS Month
returns 03 (perfect).
But when the code is like (the first zero is now a 1!) :
SELECT SUBSTRING(CAST(18022017 AS VARCHAR(38)), 2, 2) AS Month
the result is 80 because SUBSTRING now is counting from the (1) first position and in the first example it took 4 as the starting point.
Obviously I need to have 1 code for all occurrences but I just don't get it right.
Some help would be appreciated!
Regards, J
This should work for you:
select SUBSTRING(right('00000000' + CAST(04032017 AS varchar(38)),8), 3, 2) as Month
You might require to parse this as varchar and then convert into valid date and use month() function to get clear approach
declare #date nvarchar(10)='18022017'
select Month(cast(CONCAT(SUBSTRING(#date,3,2),'/',SUBSTRING(#date,1,2),'/',SUBSTRING(#date,5,4)) as date))
Ok, just solved it. Just remove the cast (why did I use that in the first place?) and put single quotes around the date:
select SUBSTRING('04032017'), 2, 2) as Month
This works just fine!
Having some columns with either empty or a date in it, I need to get a true or false for a date present.
A B C D E F
1 Name oDate eDate xDate EndDate Status
2 Lars 01-11-2015 ? <= TRUE
3 Erik ? <= FALSE
4 Niels 09-01-2015 10-02-2015 ? <= TRUE
5 Jens 02-02-2016 10-02-2015 ? <= TRUE
Tried with
=IF(COUNTIFS($AP2:$AP2;ISNUMBER($AP2);$AQ2:$AQ2;ISNUMBER($AQ2);$AR2:$AR2;ISNUMBER($AR2);$AS2:$AS2;ISNUMBER($AS2);$AT2:$AT2;ISNUMBER($AT2);$AU2:$AU2;ISNUMBER($AU2)) >= 1;"TRUE";"FALSE")
but that just checks if fields not empty.
Anyone?
To Excel dates are just numbers formatted to suit (subject to being in the range 0 - 2958465) so say 23 September 1904 is just the same as dozen gross (1,728) without added context such as formatting. Provided the formatting is as you show it can be detected to use to differentiate say 11/02/2015 from 42,046:
=OR(CELL("format",B2)="D1",CELL("format",C2)="D1",CELL("format",D2)="D1",CELL("format",B2)="D1")
However since detecting the format of cells rather than content, a blank cell formatted as a date will count even without, in that case 00/01/1990 being displayed. (So you might also want a further check, such as that the sum of B:E cells is also greater than 0, or that each is a positive number and not text.)
Please advice how to combine query, to find first occurrence of row
I have table
Date Counter
01.01.2005 208,5
02.01.2005 209,5 <----- start
03.01.2005 210,5
04.01.2005 211,5
08.01.2005 16,5
09.01.2005 17,2
10.01.2005 18,8 <------ correct
11.01.2005 19,7
12.01.2005 20,7
13.01.2005 21
14.01.2005 116,3
15.01.2005 120,4
16.01.2005 135,2
17.01.2005 1,1
18.01.2005 10,3
19.01.2005 18,7 <------ wrong
20.01.2005 14,2
21.01.2005 8,5
22.01.2005 7,1
and I need to extract Date by Counter 18.5 (from starting date 02.01.2005), since this value not in the table possible to take next higher value.
I tried to search by using starting date (because table have thousand dates and Counter between 0-499) and limit for value (grater or equal).
select top 1 Date from Tabel1 where Date > 02.01.2005 AND Counter >= 18.5
this query return wrong result - date 03.01.2005,
but correct must be 10.01.2005.
Hope for any assistance. Thanks in advance.
(I use: sql 2008 r).
You need to put an ORDER BY clause when using TOP. In this case you want to get the lowest Counter:
SELECT TOP 1 *
FROM tbl
WHERE
Date > CAST('20050102' AS DATE)
AND Counter >= 18.5
ORDER BY Counter
Note that without the ORDER BY, the result of TOP 1 is not guaranteed to always be the same.
I am new to SQL server and i am trying to get the value of the previous month (just int not date) when i have current month as parameter.
For example: how to get current-month - 1 when current-month = 1 (january)?
Sorry if it is an obvious question.
Please help me!
You can get it by using CASE
SELECT #prev_month = CASE WHEN #current_month = 1 THEN 12 ELSE #current_month - 1 END
I am trying to sum INTERVAL. E.g.
SELECT SUM(TIMESTAMP1 - TIMESTAMP2) FROM DUAL
Is it possible to write a query that would work both on Oracle and SQL Server? If so, how?
Edit: changed DATE to INTERVAL
I'm afraid you're going to be out of luck with a solution which works in both Oracle and MSSQL. Date arithmetic is something which is very different on the various flavours of DBMS.
Anyway, in Oracle we can use dates in straightforward arithmetic. And we have a function NUMTODSINTERVAL which turns a number into a DAY TO SECOND INTERVAL. So let's put them together.
Simple test data, two rows with pairs of dates rough twelve hours apart:
SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss'
2 /
Session altered.
SQL> select * from t42
2 /
D1 D2
-------------------- --------------------
27-jul-2010 12:10:26 27-jul-2010 00:00:00
28-jul-2010 12:10:39 28-jul-2010 00:00:00
SQL>
Simple SQL query to find the sum of elapsed time:
SQL> select numtodsinterval(sum(d1-d2), 'DAY')
2 from t42
3 /
NUMTODSINTERVAL(SUM(D1-D2),'DAY')
-----------------------------------------------------
+000000001 00:21:04.999999999
SQL>
Just over a day, which is what we would expect.
"Edit: changed DATE to INTERVAL"
Working with TIMESTAMP columns is a little more labourious, but we can still work the same trick.
In the following sample. T42T is the same as T42 only the columns have TIMESTAMP rather than DATE for their datatype. The query extracts the various components of the DS INTERVAL and converts them into seconds, which are then summed and converted back into an INTERVAL:
SQL> select numtodsinterval(
2 sum(
3 extract (day from (t1-t2)) * 86400
4 + extract (hour from (t1-t2)) * 3600
5 + extract (minute from (t1-t2)) * 600
6 + extract (second from (t1-t2))
7 ), 'SECOND')
8 from t42t
9 /
NUMTODSINTERVAL(SUM(EXTRACT(DAYFROM(T1-T2))*86400+EXTRACT(HOURFROM(T1-T2))*
---------------------------------------------------------------------------
+000000001 03:21:05.000000000
SQL>
At least this result is in round seconds!
Ok, after a bit of hell, with the help of the stackoverflowers' answers I've found the solution that fits my needs.
SELECT
SUM(CAST((DATE1 + 0) - (DATE2 + 0) AS FLOAT) AS SUM_TURNAROUND
FROM MY_BEAUTIFUL_TABLE
GROUP BY YOUR_CHOSEN_COLUMN
This returns a float (which is totally fine for me) that represents days both on Oracle ant SQL Server.
The reason I added zero to both DATEs is because in my case date columns on Oracle DB are of TIMESTAMP type and on SQL Server are of DATETIME type (which is obviously weird). So adding zero to TIMESTAMP on Oracle works just like casting to date and it does not have any effect on SQL Server DATETIME type.
Thank you guys! You were really helpful.
You can't sum two datetimes. It wouldn't make sense - i.e. what does 15:00:00 plus 23:59:00 equal? Some time the next day? etc
But you can add a time increment by using a function like Dateadd() in SQL Server.
In SQL Server as long as your individual timespans are all less than 24 hours you can do something like
WITH TIMES AS
(
SELECT CAST('01:01:00' AS DATETIME) AS TimeSpan
UNION ALL
SELECT '00:02:00'
UNION ALL
SELECT '23:02:00'
UNION ALL
SELECT '17:02:00'
--UNION ALL SELECT '24:02:00' /*This line would fail!*/
),
SummedTimes As
(
SELECT cast(SUM(CAST(TimeSpan AS FLOAT)) as datetime) AS [Summed] FROM TIMES
)
SELECT
FLOOR(CAST(Summed AS FLOAT)) AS D,
DATEPART(HOUR,[Summed]) AS H,
DATEPART(MINUTE,[Summed]) AS M,
DATEPART(SECOND,[Summed]) AS S
FROM SummedTimes
Gives
D H M S
----------- ----------- ----------- -----------
1 17 7 0
If you wanted to handle timespans greater than 24 hours I think you'd need to look at CLR integration and the TimeSpan structure. Definitely not portable!
Edit: SQL Server 2008 has a DateTimeOffset datatype that might help but that doesn't allow either SUMming or being cast to float
I also do not think this is possible. Go with custom solutions that calculates the date value according to your preferences.
You can also use this:
select
EXTRACT (DAY FROM call_end_Date - call_start_Date)*86400 +
EXTRACT (HOUR FROM call_end_Date - call_start_Date)*3600 +
EXTRACT (MINUTE FROM call_end_Date - call_start_Date)*60 +
extract (second FROM call_end_Date - call_start_Date) as interval
from table;
You Can write you own aggregate function :-). Please read carefully http://docs.oracle.com/cd/B19306_01/appdev.102/b14289/dciaggfns.htm
You must create object type and its body by template, and next aggregate function what using this object:
create or replace type Sum_Interval_Obj as object
(
-- Object for creating and support custom aggregate function
duration interval day to second, -- In this property You sum all interval
-- Object Init
static function ODCIAggregateInitialize(
actx IN OUT Sum_Interval_Obj
) return number,
-- Iterate getting values from dataset
member function ODCIAggregateIterate(
self IN OUT Sum_Interval_Obj,
ad_interval IN interval day to second
) return number,
-- Merge parallel summed data
member function ODCIAggregateMerge(
self IN OUT Sum_Interval_Obj,
ctx2 IN Sum_Interval_Obj
) return number,
-- End of query, returning summary result
member function ODCIAggregateTerminate
(
self IN Sum_Interval_Obj,
returnValue OUT interval day to second,
flags IN number
) return number
)
/
create or replace type body Sum_Interval_Obj is
-- Object Init
static function ODCIAggregateInitialize(
actx IN OUT Sum_Interval_Obj
) return number
is
begin
actx := Sum_Interval_Obj(numtodsinterval(0,'SECOND'));
return ODCIConst.Success;
end ODCIAggregateInitialize;
-- Iterate getting values from dataset
member function ODCIAggregateIterate(
self IN OUT Sum_Interval_Obj,
ad_interval IN interval day to second
) return number
is
begin
self.duration := self.duration + ad_interval;
return ODCIConst.Success;
exception
when others then
return ODCIConst.Error;
end ODCIAggregateIterate;
-- Merge parallel calculated intervals
member function ODCIAggregateMerge(
self IN OUT Sum_Interval_Obj,
ctx2 IN Sum_Interval_Obj
) return number
is
begin
self.duration := self.duration + ctx2.duration; -- Add two intervals
-- return = All Ok!
return ODCIConst.Success;
exception
when others then
return ODCIConst.Error;
end ODCIAggregateMerge;
-- End of query, returning summary result
member function ODCIAggregateTerminate(
self IN Sum_Interval_Obj,
returnValue OUT interval day to second,
flags IN number
) return number
is
begin
-- return = All Ok, too!
returnValue := self.duration;
return ODCIConst.Success;
end ODCIAggregateTerminate;
end;
/
-- You own new aggregate function:
CREATE OR REPLACE FUNCTION Sum_Interval(
a_Interval interval day to second
) RETURN interval day to second
PARALLEL_ENABLE AGGREGATE USING Sum_Interval_Obj;
/
Last, check your function:
select sum_interval(duration)
from (select numtodsinterval(1,'SECOND') as duration from dual union all
select numtodsinterval(1,'MINUTE') as duration from dual union all
select numtodsinterval(1,'HOUR') as duration from dual union all
select numtodsinterval(1,'DAY') as duration from dual);
Finally You can create SUM function, if you want.