I have the following query which works on SQL Server 2012 to give me the hourly average of the values in the CounterValue column:
select
dateadd(hour, datediff(hour, 0, CounterDateTime), 0),
avg(CounterValue)
from mopsxactthroughput
group by
dateadd(hour, datediff(hour, 0, CounterDateTime), 0)
I would like to, if possible, modify it so that it returns no row for an hour if there was only ONE record matching that hour. For example, if between 2013-06-06T20:00:00 and 2013-06-06T21:00:00 there was only one record, I want no row returned for that one hour period.
It strikes me as a little much to ask for of a SELECT, but maybe there is a way. (My fallback will be to return all records grouped by hour and then iterate the row set myself in Java and apply the averaging/discarding there.)
Simply add a having clause:
select
dateadd(hour, datediff(hour, 0, CounterDateTime), 0),
avg(CounterValue)
from mopsxactthroughput
group by
dateadd(hour, datediff(hour, 0, CounterDateTime), 0)
having count(*) > 1
Perhaps this CTE works:
with cte as(
select dateadd(hour, datediff(hour, 0, CounterDateTime), 0) as Hour,
avg(CounterValue)over(partition by dateadd(hour, datediff(hour, 0, CounterDateTime), 0)) as AvgCounter,
Count(*)over(partition by dateadd(hour, datediff(hour, 0, CounterDateTime), 0)) as HourCount,
CounterValue,
CounterDateTime
from mopsxactthroughput
)
select Hour, CounterValue, CounterDateTime, AvgCounter
from cte
where HourCount > 1
Related
i want to retrieve records where a date field is set to future months
does this look correct
Select * from table1 WHERE
datesetto >MONTH(dateadd(dd, -1, GetDate())))
select * from tablename where month(columndate)>month(getdate()) and
year(columndate)>=year(getdate())
SELECT * FROM table1
WHERE datesetto >= DATEADD(month, DATEDIFF(month, 0, getdate())+1, 0)
Explanation:
DATEDIFF(month, 0, getdate()) calculates how many months have passed since 1900-01-01.
DATEADD(month, DATEDIFF(month, 0, getdate()), 0) returns the beginning of this month.
DATEADD(month, DATEDIFF(month, 0, getdate())+1, 0) returns the beginning of next month.
Try this:
Select * from table1 WHERE
((DATEPART(MONTH,datesetto) > DATEPART(MONTH,GETDATE())
AND DATEPART(YEAR,datesetto) = DATEPART(YEAR,GETDATE()))
OR (DATEPART(YEAR,datesetto) > DATEPART(YEAR,GETDATE())))
DATEPART(Month,GETDATE()) will give the month of the current date and then you can compare it with the datesetto
Update: The above query will give data for any months greater than the current month and any month greater in the year than the current year.
So I have used this post as a reference, however I would like to count all the rows based on a 15 minute time period.
Here is what I have so far:
SELECT DateAdd(minute, DateDiff(minute, 0, [datetime]), 0) as Timestamp,
Count(*) as Tasks
FROM [table]
GROUP BY DateAdd(minute, DateDiff(minute, 0, [datetime]), 0)
ORDER BY Timestamp
This is great for getting rows per minute, however I need 15 minutes...
So I change:
DateAdd(minute, DateDiff(minute, 0, [datetime]), 0)
to
DateAdd(minute, DateDiff(minute, 0, [datetime]), 15)
however that is just pushing the date 15 days ahead.
Any help is appreciated!
To get 15 minutes, divide by 15 (and then multiply again):
SELECT DateAdd(minute, 15*(DateDiff(minute, 0, [datetime]) / 15), 0
) as Timestamp,
Count(*) as Tasks
FROM [table]
GROUP BY (DateDiff(minute, 0, [datetime]) / 15)
ORDER BY Timestamp;
SQL Server does integer division. If you want to be unambiguous about your intentions, use FLOOR().
SELECT ROUND(DATEDIFF(SECOND,{d '1970-01-01'},[datetime])/(15 * 60),0) as Timestamp,
Count(*) as Tasks
FROM [table]
GROUP BY ROUND(DATEDIFF(SECOND,{d '1970-01-01'},[datetime])/(15 * 60),0)
ORDER BY Timestamp
Here is an alternative in case integer division causes an issue for you. It casts the datetime as a float and then uses floor().
SELECT convert(varchar,cast(round(floor(cast([datetime] as float(53))*24*4)/(24*4),5) as smalldatetime),108) as Timestamp,
Count(*) as Tasks
FROM [table]
GROUP BY convert(varchar,cast(round(floor(cast([datetime] as float(53))*24*4)/(24*4),5) as smalldatetime),108)
ORDER BY Timestamp
I normally change the (24*4) to 96 (the number of 15 minute intervals in a day), but thought I'd leave it so people can see how to adapt it for other time periods.
Need query to get records by comparing one of it's field with different values
Here is the my table
repeated 1 means Daily
2 means Weekly
3 means Monthly
I need query to get all records which are going to Tele caste and being Tele casting by comapring current date and time.
Thank you
Do you mean something like this?
--case for daily: only need to check times
select
*
from
schedules
where
repeated = 1
--this is to compare if it starts within the next hour, may have bugs not tested
--logic is if start time - 1 hour is less than now but start time is more than now must start within the next hour
and DATEADD(day, -DATEDIFF(day, 0, dateadd(hour,startdate),-1) ), dateadd(hour,startdate),-1) ) < DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
and DATEADD(day, -DATEDIFF(day, 0, startdate), startdate) > DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
union
--case for weekly: is the day of the week the same, if so check times
select
*
from
schedules
where
repeated = 2
and datepart(dw,startdate) = datepart(dw,Now)
and DATEADD(day, -DATEDIFF(day, 0, dateadd(hour,startdate),-1) ), dateadd(hour,startdate),-1) ) < DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
and DATEADD(day, -DATEDIFF(day, 0, startdate), startdate) > DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
union
--case for monthly is the day of the month the same, if so compare times
select
*
from
schedules
where
repeated = 3
and datepart(day,startdate) = datepart(day,Now)
and DATEADD(day, -DATEDIFF(day, 0, dateadd(hour,startdate),-1) ), dateadd(hour,startdate),-1) ) < DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
and DATEADD(day, -DATEDIFF(day, 0, startdate), startdate) > DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
and is monthly based on date of the month , number of weeks (e.g. 4) or week of the month + weekday (e.g. second tuesday of the month)
EDIT: i think that should work where a monthly cycle is means on that day of the month every month.
The above could be modified to use a separate time column by just using that field for all time comparisons e.g.:
...
where
repeated = 3
and datepart(day,startdate) = datepart(day,Now)
and DATEADD(day, -DATEDIFF(day, 0, dateadd(hour,starttime),-1) ), dateadd(hour,starttime),-1) ) < DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
and DATEADD(day, -DATEDIFF(day, 0, starttime), starttime) > DATEADD(day, -DATEDIFF(day, 0, Now()), Now())
EXPLANATION:
the normal way i would process this question as a human would be:
whats the start date
whats the repeating cycle
does startdate * any multiple of repeating cycle period = today
if so is it on now
this is a procedural, step based solution
when i think of this as a set based problem then i need to know what is the set of programs that is on now
I am allowed to add sets (union) but i cannot step through rows considering each one.. so i split it into three sets and add them together:
daily shows are on every day so i only need to check times
weekly shows are on every week on the same day, so if its weekly if the days of the week matches compare times
monthly shows are on the same day of the month every months, so if its that day of the month compare the times
hope this helps.. sorry if my explanation is crap, just trying to help :D
are you looking for this :-
Declare #Today Datetime
Select #Today = Getdate()
Select s.ProgramId
,s.ProgramName
From schedules As s With (Nolock)
Where (Cast(s.startdate As Datetime) + Cast(s.StartTime As Datetime)) >= #Today
Order By s.repeated
,s.ProgramId
Example:
SELECT column_name
FROM table_name
WHERE column_name IN (value1, value2, value3)
You mean something like that?
I'm trying to get the count of each distinct field in my database. For example, we are using something called sourceCodes - I want to be able to see how many of each different sourceCode there is in my database. So far, I have this
SELECT sourceCode, COUNT(DISTINCT sourceCode)
FROM [SecureOrders]
WHERE DateTime >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
AND DateTime < DATEADD(day, DATEDIFF(day, 0, GETDATE()), 1)
GROUP BY sourceCode
(I'm trying to display the name of the sourceCode first, and then the count). So far though, the only thing I ever get in my second column is "1"...and I'm positive there are more than one. I know I worded this question really poorly, but I can't really figure out any other way to say it. Can anybody see why this is happening?
The "distinct" in your sample is not being applied at the correct place. By grouping by SourceCode, you are already getting distinct values from that column.
So, you only need to count the rows in each group:
SELECT sourceCode, COUNT(*)
FROM [SecureOrders]
WHERE DateTime >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
AND DateTime < DATEADD(day, DATEDIFF(day, 0, GETDATE()), 1)
GROUP BY sourceCode
Remove the DISTINCT:
SELECT sourceCode, COUNT(sourceCode)
FROM [SecureOrders]
WHERE DateTime >= DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
AND DateTime < DATEADD(day, DATEDIFF(day, 0, GETDATE()), 1)
GROUP BY sourceCode
Sql:
select distinct DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date,
(select count(*) from Raw_Mats A where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)) as Total,
(select count(*) from Raw_Mats B where DateAdd(Day, DateDiff(Day, 0, B.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and B.status='Solved') as Delivered,
(select count(*) from Raw_Mats C where DateAdd(Day, DateDiff(Day, 0, C.Receive_date), 0)=DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) and C.status='Pending') as UnDelivered
from Raw_Mats m where m.Receive_date between '2011-07-01' and '2011-07-21'
How to increase the performance of the above query. It is taking 44 secs . wanna make it less than 10 secs
Thanks
Do you have an index on both Receive_date and status? (not an index on each, combined)
Also:
You have have 4 touches in the table which means the query will scale at least O(4n).
By using COUNT(CASE) you can remove Delivered and UnDelivered subqueries
The simple count subquery isn't needed either
You need GROUP BY. YOur DISTINCT is a work around for that
BETWEEN is >= and <= which isn't the usually correct for dates with times
I've used a subquery here for clarity but it doesn't matter:
select
DateOnly as Date,
COUNT(*) AS Total,
COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered,
COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered
from
(
SELECT
DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as DateOnly,
status
FROM
Raw_Mats
WHERE
Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21'
) T
GROUP BY
DateOnly
Edit, without subquery.
I started with a subquery because I thought it's be more complex than expected and didn't bother taking it out...
select
DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0) as Date,
COUNT(*) AS Total,
COUNT(CASE WHEN status='Solved' THEN 1 END) AS Delivered,
COUNT(CASE WHEN status='Pending' THEN 1 END) AS UnDelivered
from
Raw_Mats
WHERE
Receive_date >= '2011-07-01' AND Receive_date < '2011-07-21'
GROUP BY
DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)
Divide and conquer: Just try each part of your sql as a separate statement and you'll find out which part is slow. If you have sub-selects and functions there is a good chance, that the server need temp-tables to perform the select, if you haven't got enough memory (or a large dataset or configured your sql server to do so), this temp-objects are swapped to disk, which makes it slow too.
Too many sub queries man! Get rid of some of them and it will help. Also you should not use functions on both sides in your sqls.
For example:
where DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0)=
DateAdd(Day, DateDiff(Day, 0, m.Receive_date), 0)
In this specific case the db engine will have to go through all the rows to evaluate DateDiff(Day, 0, A.Receive_date) and DateAdd(Day, DateDiff(Day, 0, A.Receive_date), 0) then compare it with the right hand side which also is a function! This simply is a disaster.
Also, do you have indexes on Receive_date? If not add it.