How to make a SQL looping for date? - sql-server

select CAST(convert(varchar, a.rechargedate, 112) as datetime)as RechargeDate,
COUNT(distinct a.mobileno) AS UnitTotal,
SUM(a.amount) AS AmountTotal
from recharge a
where *a.rechargedate BETWEEN '2009-07-01' AND '2009-07-31'*
group by CAST(convert(varchar, a.rechargedate, 112) as datetime)
order by a.rechargedate
above is my sql query. in the
(((( a.rechargedate BETWEEN '2009-07-01' AND '2009-07-31' )))))
i would change it by using looping. so if next time i wanna change date to august. it will automatically loops by itself. i no need to manually key in the date to 2009-08-01........
got anyone can help me ? show me how to make it?

Not sure if this is just a query that you are using for yourself to veiw data, or if it is suppose to be in a sproc. If it is just a utility query, you could do something like this.,
declare #firstofmonth as smalldatetime
declare #endofmonth as smalldatetime
--Set the inital month to loop
set #firstofmonth = '01/01/2009'
set #endofmonth = '01/31/2009'
WHILE #firstofmonth >= '09/01/2009' --This would be the condition to end the loop
Begin
select CAST(convert(varchar, a.rechargedate, 112) as datetime)as RechargeDate,
COUNT(distinct a.mobileno) AS UnitTotal,
SUM(a.amount) AS AmountTotal
From recharge a
Where a.rechargedate BETWEEN #firstofmonth AND #endofmonth
group by CAST(convert(varchar, a.rechargedate, 112) as datetime)
order by a.rechargedate
SET #firstofmonth = DateAdd(m,1,#firstofmonth)
SET #endofmonth = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#firstofmonth())+1,0))
End

it all depends on your logic, here are some options:
take #startDate and #endDate as parameters for the sproc
if you can logically tie those dates to current date, you can calculate them in the sproc (or function) based on getdate() (will give you current date)

Related

TSQL Search Query between two dates

I am having a little trouble figuring out how to write a query that seems pretty straight forward.
The problem is in my WHERE clause. There are two fields in my table. A timestamp for when the task has started startTime and a timestamp for when the task was completed endTime/ Both of these fields are Datetime.
In my UI, I allow the person to select a Start Date and End Date and their filtering option.
The date logic should be as follows:
Everything where the StartTime is >= #startDate but < #endDate and the EndTime is <=#endDate but > #startDate.
I have done date ranges before using a single date in the database but not multiple so I am confused.
Any thoughts?
-- Fetch our data
SELECT [recordID],
[ItemID],
[QID],
[NTID],
[EmpID],
[FirstName],
[LastName],
[SupQID],
[SupEmpID],
[SupFirstName],
[SupLastName],
[Location],
[Department],
[Skillset],
[BudgetMarket],
CONVERT (VARCHAR (20), [startTime], 100) AS startTime,
CONVERT (VARCHAR (20), [endTime], 100) AS endTime,
COALESCE (DATEDIFF(SECOND, startTime, endTime), 0) AS totalTimeSeconds
FROM itemTracker_records
WHERE (#employee IS NULL OR (QID = #employee))
AND (#supervisor IS NULL OR (supQID = #supervisor))
AND CAST(endTime as Date) >= #startDate AND CAST(endTime as Date) < #endDate
FOR XML PATH ('results'), TYPE, ELEMENTS, ROOT ('root');
Shouldn't it be as simple as :
WHERE (StartTime >= #startDate AND #startDate < #endDate )
AND (EndTime <= #endDate AND #endDate > #startDate)
Or, slightly shorter:
WHERE StartTime between #startDate AND #endDate
AND EndTime between #startDate AND #endDate
Assuming "good" data, i.e. tasks always end after they start and the user supplied range is valid:
where startTime >= #StartDate and endTime <= #EndDate
As long as that is true then the task time span must be contained within the user specified range.
Note that a common problem is attempting to find date/time values between a pair of dates. To include all times on the last day it is necessary to add one day to #EndDate and remove equality from the comparison.

Show 0 if null in query

I am running a sql query that is omitting the day if the return count is 0. I want my query to return the day and a 0 count if the the count is 0. Snare I have is that if 0 were sold for the day, the day is omitted from my return results.
SELECT ISNULL([day],0) As [day], COUNT(ISNULL(Sold,0)) As [Sold]
FROM productionInfo
You're drawing information from a single table, productionInfo. If productionInfo has no rows with that date information (because there are no widgets sold on that date), how does it know what dates to use?
You might want to look at using a Numbers Table to get a row for each day of the month/year, then join that to productionInfo so you have a day value available, even if there was no production that day.
This will give you a dates table:
CREATE FUNCTION dbo.DatesTable (#startDate DATETIME, #endDate DATETIME)
RETURNS #retTable TABLE (DateValue DATETIME)
AS
BEGIN
DECLARE #currentDate DATETIME
SET #currentDate = #startDate
WHILE (DATEDIFF(dd, #currentDate, #endDate) >= 0)
BEGIN
INSERT INTO #retTable VALUES (#currentDate)
SET #currentDate = DATEADD(dd, 1, #currentDate)
END
RETURN
END
Then your query will look like:
SELECT dt.DateValue AS [day], COUNT(Sold) AS [Sold]
FROM dbo.DatesTable('2-1-2014', '2-10-2014') dt
LEFT JOIN productionInfo pi ON pi.day = dt.DateValue
GROUP BY dt.DateValue

TSQL Filtering a query by time / hours

Ok, I'm running query builder out of visual studio 2008. I'm trying to filter the results of the query by time; that is, I want to pull everything from the start of yesterday to noon yesterday.
I've been using GETDATE()-1 for yesterday, which pulls up a timestamp mm/dd/yyyy hh:mm:ss
however, it pulls the current time. to get it to run from the start of the day I appended the timestamp to remove the time itself, so it started at the beginning of the day:
convert(varchar(10), getdate()-1, 120)
so I'm using between to find the range, I have:
BETWEEN convert(varchar(10), getdate()-1, 120) AND // this is where I need it to cut off at noon.
I'm understanding that datetime is a data type here, so I tried subtracting the hours/minutes/seconds using date part, but datepart() only returns ints and doesn't affect the time.
thoughts? how do I get this to cut off at noon
Try this:
--Variables
declare #now datetime = getdate(),
#yesterday datetime
--Yesterday starting datetime
select #yesterday = convert(datetime, convert(date, dateadd(day,-1,#now)))
--Your query to filter between y'day start and y'day noon
--Note that between means inclusive boundary values. (or use >= and <=)
select * from yourTable
where dateCol between #yesteray and dateadd(hour,12,#yesterday)
DECLARE
#Min DATETIME
, #Max DATETIME
SELECT
#Min = DATEADD(DAY, -1, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))
, #Max = DATEADD(HOUR, 12, CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME))
SELECT *
FROM <Table> x
WHERE x.[Date] BETWEEN #Min AND #Max
SELECT * FROM T WHERE YourDate BETWEEN CAST(GETDATE()-1 As DATE) AND DATEADD(Hour, -12, CAST(CAST(GETDATE() As DATE) As DATETIME) )
Beware because BETWEEN will include lower and upper boundaries, so you can simply replace BETWEEN with x >= y and y < z if you don't want yesterday at 12:00 to be taken in account
between DateAdd(day, -1, cast(getdate() as date)) and DateAdd(hour, -12, cast(getdate() as date))
Edit: As mentioned in the comments, you can't use hours with a date, you have to cast it back to a datetime, thus:
between DateAdd(day, -1, cast(getdate() as date)) and DateAdd(hour, -12, cast(cast(getdate() as date) as datetime))
If you want to get the results from last 30 mins you need to use this. You can change MINUTE to HOUR too.
--Get now, hour and second included
DECLARE #NOW DATETIME = GETDATE()
--Get 30 mins from now
DECLARE #TranDate DATETIME
SET #TranDate = CONVERT(DATETIME, CONVERT(DATETIME, DATEADD(MINUTE,-30,#NOW)))
After That, add below code to your where statement,
AND TK.TransactionDate >= #TranDate

SQL Server - Generate date field data in where clause

My query is
Select * from Orders
where ordersdate Between '2013-10-10 00:00:00.00' and '2013-10-10 23:59:59.997'
I need to run this query on daily basis and it should be previous day dates. so how to generate dates in above format is what im struggling with.
Select *
from Orders
where ordersdate >= cast(dateadd(d, -1, getdate()) as date)
and ordersdate < cast(getdate() as date)
Instead of the additonal time you can use >= yesterday's date and < today.
DECLARE #StartDate DATETIME, #EndDate DATETIME
/* set the end date to midnight of the previous day */
SET #EndDate = CONVERT(DATETIME, CONVERT(VARCHAR(10), GETDATE(), 121), 121)
/* set the start date to 1 day previously (thereby getting midnight to midnight) */
SET #StartDate = DATEADD(day, -1, #EndDate)
/* you could use between, but orders placed at midnight might be counted twice (on subsequent day reports) */
Select * from Orders where ordersdate Between #StartDate AND #EndDate
/* or you could use >= and < to guarantee that a order placed at midnight will only be counted once */
Select * from Orders where ordersdate >= #StartDate AND ordersdate < #EndDate
select *
from orders
where datediff(d, ordersdate, getdate()) = 1
/edit/
As per Jason Musgrove comment - such query is easy to write and understand, but depend on rows count may become quite inefficent.
taking a slightly different approach (but probably not as good as Arvo's Answer) and there are quicker ways to perform the cast
select *
from orders
where cast(ordersdate as varchar(11)) = cast( dateadd(dd,-1,getdate()) as varchar(11) )

Only Date Part comparison with System Date in SQL Server

I have a stored procedure :-
CREATE procedure St_Proc_GetTimeEntryID
#userID int,
#timeEntryID int output
as begin
set nocount on;
SET #timeEntryID=0
DECLARE #TEMP INT
SET #TEMP=0
SELECT #TEMP=ProductionTimeEntryID
FROM production
WHERE ProductionTimeEntryID =
(SELECT MAX(ProductionTimeEntryID)
FROM production
where UserID=#userID
and (CalendarDate = (select GETDATE()))
and IsTaskCompleted=1 )
BEGIN
SET #timeEntryID=#TEMP
END
END
Here CalendarDate is column which containing Date As 06/26/201212:00PM format .
I want to compare the date part only with system date part (06/26/2012 = 06/26/2012) in my subquery which is
(SELECT MAX(ProductionTimeEntryID)
FROM production
where UserID=#userID
and (CalendarDate = (select GETDATE()))
and IsTaskCompleted=1 )
Please guide me what modification i ll do to get the result.
In SQL2K8;
... WHERE CAST(CalendarDate AS DATE) <= CAST(GETDATE() AS DATE)
(This will negate any index use on CalendarDate, alternatively bracket CalendarDate between CalendarDate >= CAST(CalendarDate AS DATE) AND < DATEADD(...)
The most efficient method (meaning fully able to utilize an index on CalendarDate, if one exists) is going to be, on SQL Server 2000/2005:
DECLARE #today SMALLDATETIME;
SET #today = DATEDIFF(DAY, 0, CURRENT_TIMESTAMP);
...
WHERE CalendarDate >= #today
AND CalendarDate < DATEADD(DAY, 1, #today);
If using SQL Server 2008+:
DECLARE #today DATE = CURRENT_TIMESTAMP;
...
WHERE CalendarDate >= #today
AND CalendarDate < DATEADD(DAY, 1, #today);
You can also use a direct cast in SQL Server 2008+, but I'm not 100% sure this is guaranteed to use an index on CalendarDate in all scenarios:
WHERE CONVERT(DATE, CalendarDate) = CONVERT(DATE, CURRENT_TIMESTAMP);
Because this casting does not work with other date/time data types, for consistency I much prefer the open-ended range technique, and definitely do not condone most of the scenarios where you perform implicit or explicit conversions on the column (since this usually means an index won't be used). I've ranted about this and several other date/time atrocities plenty at the following blog posts:
What do BETWEEN and the devil have in common?
Bad habits to kick : mis-handling date / range queries
Something like this?
(SELECT MAX(ProductionTimeEntryID)
FROM production
where UserID=412
and (convert(datetime, convert(varchar(100), CalendarDate, 106)) <= convert(datetime, convert(varchar(100), GETDATE(), 106)))
and IsTaskCompleted=1 )
Use convert function
In your case:
SELECT CONVERT(DATE,GETDATE(),101)
More specifically:
(SELECT MAX(ProductionTimeEntryID)
FROM production
where UserID=#userID
and (CONVERT(DATE,CalendarDate) = CONVERT(DATE,GETDATE()))
and IsTaskCompleted=1 )

Resources