SQL Server 2008 : Avg. timing in milliseconds - sql

I have this query
select
substring((convert(varchar, PostTime, 120)), 1, 11),
AccountNumber,
sum(Cast(datediff(ss, TranTime, AuthProcessedTime) as money)) / COUNT(1) AverageTime,
COUNT(1) NumberOfCount
from
AuthTransactions WITH (NOLOCK)
group by
substring((convert(varchar, PostTime, 120)), 1, 11), AccountNumber
In this query AverageTime comes in sec. but I want to see it in the following format HH:MM:SS.msmsms because most of the time results come in milliseconds. So is it possible to see the result in this format?
Thanks in advance.

Try this:
SELECT
Convert(date, PostTime) PostDay
AccountNumber,
Avg(Datediff(ms, TranTime, AuthProcessedTime) * 1.0) AverageTime,
Count(*) NumberPerDay
FROM
dbo.AuthTransactions
GROUP BY
Convert(date, PostTime),
AccountNumber
There were several problems with the query that I eliminated or corrected:
Always specify a length for the char data types.
Don't convert dates to strings to remove the time portion. Use DateDiff and DateAdd, or since you're using SQL 2008 you can convert to date.
Don't use WITH (NOLOCK) unless you really know what you're doing. It will eventually bite you.
Don't convert to money. That's just weird. It has 2 decimal places, and if you really want that, then convert to decimal([something], 2). Otherwise someone is going to see your code and go "what the heck?" and 'fix' it for you, even if that's what you wanted. You can get a sufficiently-precise decimal conversion just by multiplying by 1.0 like I showed.
Do specify the schema of objects. It is small, but it helps performance and (if I am not remembering incorrectly) not doing so can cause unnecessary plan recompilation.

In your datediff(ss,TranTime,AuthProcessedTime)
change the ss to ms.
ms is used for milli second.
like this
select substring((convert(varchar,PostTime,120)),1,11),
AccountNumber,
sum(Cast (datediff(ms,TranTime,AuthProcessedTime) as money)) / COUNT(1)
AverageTime,COUNT(1) NumberOfCount from AuthTransactions
WITH(NOLOCK) group by
substring((convert(varchar,PostTime,120)),1,11),AccountNumber

Related

How to get the sum of hour, minutes, and seconds in 2 columns?

I'm using SQL Server as database. I have 2 columns in a table, newTime, oldTime.
Suppose I have value of 04:07:28 in the newTime column, and for oldTime, the value is 03:07:40.
The result should get the total of newTime and oldTime columns which is 07:15:08.
I tried the Split_String() function to easily split the numbers into hours, minutes, and seconds. But I have an issue in database the compatibility level is low and also I tried to set the compatibility_level to 130 but I don't have permission to alter the database.
Is there any other way to sum up the two columns? Thank you!
As mentioned in comments - if you're storing time values, you should really be using the TIME datatype - not a VARCHAR ..... always use the most appropriate datatype - no exceptions.
Anyway - since you have VARCHAR, the statement get a bit convoluted - but here you go:
SELECT
DATEADD(SECOND, DATEDIFF(SECOND, 0, CAST(NewTime AS TIME)), CAST(OldTime AS TIME))
FROM
dbo.YourTableNameHere
which would look a lot easier with TIME columns, of course:
SELECT
DATEADD(SECOND, DATEDIFF(SECOND, 0, NewTime), OldTime)
FROM
dbo.YourTableNameHere

MM/DD comparison issue in SQL

I am using below SQL query to get data by mentioning date range without year.
Select * from table where Left(Convert(Varchar(10),Cast(createddate As Date),101),5) between '11/01' and '12/31'
The above query works say when the user enter the date range as '11/01' to '12/31'. But, when the user enters anything like '11/01' to '01/31' or '05/31' to 02/28' etc, the query is not returning any data.
Is it possible to make it work for above ranges?
I would use the month() function:
Select *
from table
where month(nm_birthdate) in (11, 12);
Your query, however, should work because 101 zero-pads days and months.
If you want to find birthdays between two dates in MM/DD format, you could do:
where (#startmmdd < #endmmdd) and convert(varchar(5), nm_birthdate, 101) between #startmmdd and #endmmdd) or
(#startmmdd > #endmmdd) and convert(varchar(5), nm_birthdate, 101) not between #endmmdd and #startmmdd)
There might be a little adjustment depending on whether or not you want to include the end points.
Notes:
The variables #startmmdd and #endmmdd need to be in MM/DD format. Leading zeros are needed for months and days less than 10.
Convert conveniently uses the length of the data type, so left() is not necessary.
Use DATEPART, something like this:
SELECT * FROM table WHERE datepart(month, birthdate) IN (11, 12)
Of course, you can combine it with:
datepart(day, birthdate)
in order to get more complex condition.
Hope it helps

Ignore seconds and milliseconds FROM GETDATE() in SQL

I wanted to remove/ignore the seconds and milliseconds coming from GETDATE() SQL function.
When I executed,
SELECT GETDATE()
output will be like
2015-01-05 14:52:28.557
I wanted to ignore seconds and milliseconds from above output. What is the optimize and best way to do this?
I have tried to do this by typecasting like this:
SELECT CAST(FORMAT(GETDATE(),'yyyy-MM-dd HH:mm:0') AS datetime)
Is it is the correct and optimize way to do this?
I'd either use the DATEADD/DATEDIFF trick that Codo has shown or just cast it to smalldatetime1:
select CAST(GETDATE() as smalldatetime)
I'd avoid anything that involves round-tripping the value through a string.
1It may be appropriate, at this time, to change your schema to use this data type anyway, if seconds are always irrelevant.
Try this:
SELECT dateadd(minute, datediff(minute, 0, GETDATE()), 0)
The query uses the fact that DATEDIFF return the number of minutes between two dates, ignoring the smaller units. 0 is a fixed date in the past.
It can be easily adapted to other time units.
I think your way is fine if it works (looks like it should, but I haven't tested it.) There are lots of other possible approaches, too. Here's one:
select cast(convert(char(16), getdate(), 120) as datetime)

how to use like and between in where clause in same statement?

Im trying to find a set of results in a database based on dates. The dates are stored as varchars in the format dd/mm/yyyy hh:mm:ss.
What i would like to do is search for all dates within a range of specified dates.
For example i tried:
SELECT * FROM table_name
WHERE fromDate BETWEEN LIKE '%12/06/2012%' AND LIKE '%16/06/2012%'
Is something like this possible or is there a better way of doing this type of statement, because so far i have had little success?
I'm using Microsoft SQL server 2008.
Peter
Since your date values also include time, you can't use BETWEEN. The only safe way to do this is:
SELECT <cols> FROM dbo.table_name
WHERE CONVERT(DATE, fromDate, 103) >= '20120612'
AND CONVERT(DATE, fromDate, 103) < '20120617';
But as Martin noticed, you'll never be able to use an index on that column, so this will always perform a full table scan.
If you really, really want to use BETWEEN, converting to DATE is the only safe way to do so (well, or trimming the time off in other, less efficient ways):
SELECT <cols> FROM dbo.table_name
WHERE CONVERT(DATE, fromDate, 103) BETWEEN '20120612' AND '20120616';
But for consistency reasons I recommend against between even in that case.
Try This
SELECT * FROM table_name
WHERE Convert(Date,fromDate,103)
BETWEEN '20120612' AND '20120616'
The best solution is to store your varchars as DateTime in the database.
Second best is to convert then to dates in the select (as the other answers just indicates so I am not going to give the example)
The following works fine for me. Try this:
SELECT *
FROM [MABH-Desi-Dera].[dbo].[Order]
WHERE (CONVERT(nvarchar,[Order_ID]) BETWEEN '200622%' AND '200623%')
Here the Order_IDs start with some Date:
hi man this is not a rocket science bro
just make a logic like
Blockquote
SELECT * FROM table_name
WHERE fromDate BETWEEN '2021-05-01 12:00:00' AND '2021-05-01 23:59:00'
Blockquote
it will work I stuck too but it helps. i was also trying make a logic like u

Best approach to remove time part of datetime in SQL Server

Which method provides the best performance when removing the time portion from a datetime field in SQL Server?
a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
or
b) select cast(convert(char(11), getdate(), 113) as datetime)
The second method does send a few more bytes either way but that might not be as important as the speed of the conversion.
Both also appear to be very fast, but there might be a difference in speed when dealing with hundreds-of-thousands or more rows?
Also, is it possible that there are even better methods to get rid of the time portion of a datetime in SQL?
Strictly, method a is the least resource intensive:
a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
Proven less CPU intensive for the same total duration a million rows by someone with way too much time on their hands: Most efficient way in SQL Server to get a date from date+time?
I saw a similar test elsewhere with similar results too.
I prefer the DATEADD/DATEDIFF because:
varchar is subject to language/dateformat issues
Example: Why is my CASE expression non-deterministic?
float relies on internal storage
it extends to work out first day of month, tomorrow, etc by changing "0" base
Edit, Oct 2011
For SQL Server 2008+, you can CAST to date i.e. CAST(getdate() AS date). Or just use date datatype so no time to remove.
Edit, Jan 2012
A worked example of how flexible this is: Need to calculate by rounded time or date figure in sql server
Edit, May 2012
Do not use this in WHERE clauses and the like without thinking: adding a function or CAST to a column invalidates index usage. See number 2 here Common SQL Programming Mistakes
Now, this does have an example of later SQL Server optimiser versions managing CAST to date correctly, but generally it will be a bad idea ...
Edit, Sep 2018, for datetime2
DECLARE #datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE #datetime2epoch datetime2 = '19000101'
select DATEADD(dd, DATEDIFF(dd, #datetime2epoch, #datetime2value), #datetime2epoch)
In SQL Server 2008, you can use:
CONVERT(DATE, getdate(), 101)
Of-course this is an old thread but to make it complete.
From SQL 2008 you can use DATE datatype so you can simply do:
SELECT CONVERT(DATE,GETDATE())
In SQL Server 2008, there is a DATE datetype (also a TIME datatype).
CAST(GetDate() as DATE)
or
declare #Dt as DATE = GetDate()
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)
...is not a good solution, per the comments below.
I would delete this answer, but I'll leave it here as a counter-example since I think the commenters' explanation of why it's not a good idea is still useful.
Here's yet another answer, from another duplicate question:
SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime)
This magic number method performs slightly faster than the DATEADD method. (It looks like ~10%)
The CPU Time on several rounds of a million records:
DATEADD MAGIC FLOAT
500 453
453 360
375 375
406 360
But note that these numbers are possibly irrelevant because they are already VERY fast. Unless I had record sets of 100,000 or more, I couldn't even get the CPU Time to read above zero.
Considering the fact that DateAdd is meant for this purpose and is more robust, I'd say use DateAdd.
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)
I really like:
[date] = CONVERT(VARCHAR(10), GETDATE(), 120)
The 120 format code will coerce the date into the ISO 8601 standard:
'YYYY-MM-DD' or '2017-01-09'
Super easy to use in dplyr (R) and pandas (Python)!
BEWARE!
Method a) and b) does NOT always have the same output!
select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)
Output: 2014-01-01 00:00:00.000
select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)
Output: 2013-12-31 00:00:00.000
(Tested on MS SQL Server 2005 and 2008 R2)
EDIT: According to Adam's comment, this cannot happen if you read the date value from the table, but it can happen if you provide your date value as a literal (example: as a parameter of a stored procedure called via ADO.NET).
See this question:
How can I truncate a datetime in SQL Server?
Whatever you do, don't use the string method. That's about the worst way you could do it.
Already answered but ill throw this out there too...
this suposedly also preforms well but it works by throwing away the decimal (which stores time) from the float and returning only whole part (which is date)
CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)
second time I found this solution... i grabbed this code off
CAST(round(cast(getdate()as real),0,1) AS datetime)
This method does not use string function. Date is basically a real datatype with digits before decimal are fraction of a day.
this I guess will be faster than a lot.
For me the code below is always a winner:
SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT,GETDATE())));
select CONVERT(char(10), GetDate(),126)
Strip time on inserts/updates in the first place. As for on-the-fly conversion, nothing can beat a user-defined function maintanability-wise:
select date_only(dd)
The implementation of date_only can be anything you like - now it's abstracted away and calling code is much much cleaner.
I think you mean
cast(floor(cast(getdate()as float))as datetime)
real is only 32-bits, and could lose some information
This is fastest
cast(cast(getdate()+x-0.5 as int)as datetime)
...though only about 10% faster(about 0.49 microseconds CPU vs. 0.58)
This was recommended, and takes the same time in my test just now:
DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
In SQL 2008, the SQL CLR function is about 5 times faster than using a SQL function would be, at 1.35 microseconds versus 6.5 microsections, indicating much lower function-call overhead for a SQL CLR function versus a simple SQL UDF.
In SQL 2005, the SQL CLR function is 16 times faster, per my testing, versus this slow function:
create function dateonly ( #dt datetime )
returns datetime
as
begin
return cast(floor(cast(#dt as float))as int)
end
How about select cast(cast my_datetime_field as date) as datetime)? This results in the same date, with the time set to 00:00, but avoids any conversion to text and also avoids any explicit numeric rounding.
I think that if you stick strictly with TSQL that this is the fastest way to truncate the time:
select convert(datetime,convert(int,convert(float,[Modified])))
I found this truncation method to be about 5% faster than the DateAdd method. And this can be easily modified to round to the nearest day like this:
select convert(datetime,ROUND(convert(float,[Modified]),0))
Here I made a function to remove some parts of a datetime for SQL Server. Usage:
First param is the datetime to be stripped off.
Second param is a char:
s: rounds to seconds; removes milliseconds
m: rounds to minutes; removes seconds and milliseconds
h: rounds to hours; removes minutes, seconds and milliseconds.
d: rounds to days; removes hours, minutes, seconds and milliseconds.
Returns the new datetime
create function dbo.uf_RoundDateTime(#dt as datetime, #part as char)
returns datetime
as
begin
if CHARINDEX( #part, 'smhd',0) = 0 return #dt;
return cast(
Case #part
when 's' then convert(varchar(19), #dt, 126)
when 'm' then convert(varchar(17), #dt, 126) + '00'
when 'h' then convert(varchar(14), #dt, 126) + '00:00'
when 'd' then convert(varchar(14), #dt, 112)
end as datetime )
end
Just in case anyone is looking in here for a Sybase version since several of the versions above didn't work
CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
Tested in I SQL v11 running on Adaptive Server 15.7
If possible, for special things like this, I like to use CLR functions.
In this case:
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime DateOnly(SqlDateTime input)
{
if (!input.IsNull)
{
SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);
return dt;
}
else
return SqlDateTime.Null;
}
I, personally, almost always use User Defined functions for this if dealing with SQL Server 2005 (or lower version), however, it should be noted that there are specific drawbacks to using UDF's, especially if applying them to WHERE clauses (see below and the comments on this answer for further details). If using SQL Server 2008 (or higher) - see below.
In fact, for most databases that I create, I add these UDF's in right near the start since I know there's a 99% chance I'm going to need them sooner or later.
I create one for "date only" & "time only" (although the "date only" one is by far the most used of the two).
Here's some links to a variety of date-related UDF's:
Essential SQL Server Date, Time and DateTime Functions
Get Date Only Function
That last link shows no less than 3 different ways to getting the date only part of a datetime field and mentions some pros and cons of each approach.
If using a UDF, it should be noted that you should try to avoid using the UDF as part of a WHERE clause in a query as this will greatly hinder performance of the query. The main reason for this is that using a UDF in a WHERE clause renders that clause as non-sargable, which means that SQL Server can no longer use an index with that clause in order to improve the speed of query execution. With reference to my own usage of UDF's, I'll frequently use the "raw" date column within the WHERE clause, but apply the UDF to the SELECTed column. In this way, the UDF is only applied to the filtered result-set and not every row of the table as part of the filter.
Of course, the absolute best approach for this is to use SQL Server 2008 (or higher) and separate out your dates and times, as the SQL Server database engine is then natively providing the individual date and time components, and can efficiently query these independently without the need for a UDF or other mechanism to extract either the date or time part from a composite datetime type.
I would use:
CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
)
Thus effectively creating a new field from the date field you already have.