I'm trying to get a query that will multiply a static number by the amount of days in a date range the problem i'm having is that when a single day is selected it returns a result of 0 instead of 1: Ex:
Declare #Startdate DATE
Declare #enddate DATE
SET #Startdate='9/1/2013'
SET #enddate='9/1/2013'
SELECT 1154*(Select DATEDIFF(DAY, #startdate, #enddate))
This example returns 0 instead of 1. Should I be using something other than DateDiff?
Additional clarification - This will be used as part of a report where the date range will be dynamically entered by person calling the report.
Could just add 1:
Declare #Startdate DATE
Declare #enddate DATE
SET #Startdate='9/1/2013'
SET #enddate='9/1/2013'
SELECT (DATEDIFF(day,#Startdate,#enddate)+1)*1154
Update, as noted don't need the inner SELECT
Related
I have a process where I want to pass multiple dates that have not been loaded to my foreach loop container to iterate through dates one at a time. if there are no start dates in the table that have been loaded I have the isnull in the where clause to tell it to start on the min date from that table. Currently if there is a date in the table that has been loaded it will grab the next calendar date from the table to process but wont loop through all the dates. My goal is to have it pass all dates that have not been loaded and iterate through each date one at a time. So what I would like to do is to take the min and max date from ods.CalendarDate and load everything between those dates and including those dates that has not been loaded to dbo.Customerinformation. Below is my query at the moment, please help me right this to where it will select all the dates that have not been processed from the table. Thank you
DECLARE #ProcessAllDataSet BIT = ?
DECLARE #StartDate Date =?
DECLARE #EndDate date = ?
IF #LoadFullDataSet = 1
BEGIN
SELECT #StartDate = MIN(StartDate),
#EndDate = Max(StartDate) FROM dbo.CustomerInformation
END
SELECT DateProcessed = MIN(DateCalendar)
FROM ods.CalendarDate c
WHERE c.CalendarDate > ISNULL(#EndDate,'2001-01-01')
I think you're pretty close. I'm assuming ods.CalendarDate is a table of calendar dates. If so, just modify your query to return all the dates between your #StartDate and #EndDate. Make sure you set your ResultSet property of the Execute SQL Task to Full Result Set and map the results to an Object-type SSIS variable.
DECLARE #ProcessAllDataSet BIT = ?
DECLARE #StartDate Date =?
DECLARE #EndDate date = ?
IF #ProcessAllDataSet = 1
BEGIN
SELECT
#StartDate = MIN(StartDate),
#EndDate = Max(StartDate)
FROM dbo.CustomerInformation
END
SELECT
DateProcessed = DateCalendar
FROM ods.CalendarDate c
WHERE c.CalendarDate BETWEEN ISNULL(#StartDate,'2001-01-01') AND ISNULL(#EndDate,'2100-01-01')
Then set your Foreach Loop to use the Foreach ADO Enumerator and use your Object variable as the ADO object source variable. Map the DateProcessed field to a Date variable and then you can use that Date variable as you iterate through process.
I've been trying to get this work over two days and still stuck. Any assistance or tips would be greatly appreciated.
Creating a function for the date conversion:
CREATE FUNCTION LocalDateFromUTCTime
(
#UTCDateTime datetime
)
RETURNS datetime
BEGIN
DECLARE #diff int;
SET #diff = datediff(hh,GetUTCDate(), GetDate());
RETURN DATEADD(day, DATEDIFF(day, 0, DATEADD(hh, #diff, #UTCDateTime)),0);
END
Then select SQL statement I'm trying to use with the function above is below:
SELECT
o.Number AS 'Order#',
o.[guid] as 'guid',
dbo.LocalDateFromUTCTime(o.settlementdate) as 'closing date'
FROM pf.order o
doing this displays the settlement date with no timestamp.
2015-07-15 00:00:00.000
How could I change this to show the correct Local time?
Thanks
Your date conversion is specifically returning the difference in days. The dateadd is adding the number of days between date 0 (which is actually 01-01-1900) and your UTC date onto a different date 0. This means that the hours and minutes are completely ignored.
If you want to include the hours and minutes you just need to drop the dateadd(...datediff( part:
RETURN DATEADD(hh, #diff, #UTCDateTime)
I have a simple sql below. I want to calculate the daily average. But I will have to change the parameters and the number of days every day when I run my sql. What is a better way to eliminate these repeated steps?
Declare start_dt as datetime
Declare end-dt as datetime
Set start_dt ='10/01/16'
Set end_dt = '10/31/16
Select
Product_Name,
Count(Qty) /30 --want to calculate the average last 30 days
From temp
Where delivery_dt >=start_dt
And delivery_dt<end_dt
Group by product_name
As noticed above, I have to manually change the parameters for the date range and the numbers of days to get my average. Is there a way in sql server that I don't have to change the parameters and numbers of my average? And I would like my average results shown as float.
Maybe this can help you.
DECLARE #Start_dt DATETIME
DECLARE #End_dt DATETIME
SET #Start_dt = GETDATE()
SET #End_dt = DATEADD(DAY, 30, #Start_dt);
SELECT Product_Name,
Count(Qty)/DATEDIFF(DAY,#Start_dt,#End_dt) AS [Daily Average] --want to calculate the average last 30 days
FROM temp
WHERE (delivery_dt >= #Start_dt) AND (delivery_dt < #End_dt)
GROUP BY Product_Name
However, you've mentioned that you often use this kind of sql query so I would recommend that you create stored procedure for this one and just call it a day.
For creating procedures you can take a look at microsoft documentation.
You can create a stored procedure with parameter endDate and dateDifference,
for example:
CREATE PROCEDURE usp_Get_Average_Quantiity(#EndDate DateTime, #DateDifference int)
AS
Declare #StartDate DateTime = DATEADD(Day, #DateDifference, #EndDate)
Select
Product_Name,
CAST(COUNT(Qty) AS FLOAT) / #DateDifference -
From temp
Where delivery_dt >=#StartDate
And delivery_dt<#EndDate
Group by product_name
To return float I use:
CAST(COUNT(Qty) AS FLOAT) / #DateDifference
#DateDifference will probably be 30 in your case, but you can change it according to your specific scenario without changing the procedure. Same is with endDate.
I have created a procedure which returns time difference in minutes between 2 time i.e. ShiftStartTime, ShiftEndtime.
Now problem is that if i pass 2 date ranges then how i will calculate total shiftTime between those 2 dates e.g. TimeDifference returns me 480 min for today but i want to find total ShiftDifference for 3 days or more, then how i will add TimeDifference for more than 1 day ?
CREATE PROCEDURE GetShiftTotalDuration
#ShiftID int = 9,
#FromDate DateTime,
#ToDate DateTime
AS
BEGIN
Declare #TimeDifference int
Declare #ShiftStartTime time
Declare #ShiftEndTime time
Set #ShiftStartTime = (Select DeparmentShiftsHistory.StartTime from DeparmentShiftsHistory
where DeparmentShiftsHistory.Shift_ID= 9)
Set #ShiftEndTime = (Select DeparmentShiftsHistory.EndTime from DeparmentShiftsHistory
where DeparmentShiftsHistory.Shift_ID= 9)
Set #TimeDifference = (Select DATEDIFF(mi,#ShiftStartTime,#ShiftEndTime)) --Returns time difference in seconds
END
GO
I will calculate total shiftTime between those 2 dates
You mention that you will calculate difference between two dates but in your code you declare the variables as time
Declare #ShiftStartTime time
Declare #ShiftEndTime time
Thus DATEDIFF(mi,#ShiftStartTime,#ShiftEndTime) only the difference between the times not the dates
If you want to get the difference between dates you need use datetime datatype
On a side note, you have declared input parameters which have not been used in the proocedure as mentioned by Pradeep
I want to limit a report to return records from Date A through Date B. This is what I have been doing:
declare #startDate varchar(20)
declare #endDate varchar(20)
set #startDate = '01/01/2008'
set #endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections
where date between #startDate and #endDate
... which I was told returned records from 12 am Jan 1st through 11:59 pm March 31st (that midnight is the default when no time is indicated). But I noticed a discrepancy, which is if a record has a time of 00:00:00 that it will be part of this set.
Is there a more exact way of doing this so it will return exactly the date range I want?*
I tried using time:
declare #startDate varchar(20)
declare #endDate varchar(20)
set #startDate = '01/01/2008 00:00:00'
set #endDate = '04/01/2008 11:59:59'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections
where date between #startDate and #endDate
... but I noticed something wonky: SQL Server will ROUND the hundreth-second up by half. So I get that April 1st record (ha! April Fool's record! grr) if I use any time later than 11:59:29. Why is that?
(I feel sure there is. I'm new at this. Thanks for your help!)
There's always the easy option:
declare #startDate varchar(20)
declare #endDate varchar(20)
set #startDate = '01/01/2008'
set #endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections
where date >= #startDate
and date < #endDate
I suspect that the date column in view_Inspections is a SmallDateTime data type. This data type has 1 minute accuracy, which explains your unexpected results (rounding the seconds to the nearest minute).
The method Roland Shaw suggests is the best way to modify your query to accommodate your requirements.
The BETWEEN operator is inclusive, which is why you're seeing the results that you are in your first query. The rounding that you're seeing in your second query is going to be dependent on what exact datetime data type you are using in your table. (BTW, I think you're confusing seconds with hundredths of seconds). It looks like you're probably using a smalldatetime in your table, in which case the time is rounded to the nearest minute.
If your table is using datetime, try explicitly converting your #startDate and #endDate to DATETIME values (CAST(#endDate AS DATETIME)).
A quick note... even for DATETIME values, SQL Server is only accurate to the 3/100ths of a second, so 11:59:59.999 will get rounded up to 12:00:00.000.
You basically have three choices:
1) BETWEEN CAST('01/01/2008 00:00:00.000' AS DATETIME) AND CAST('03/31/2008 12:59:59.997' AS DATETIME)
2) YEAR(my_date) = 2008 AND MONTH(my_date) BETWEEN 1 AND 3
3) my_date >= CAST('01/01/2008 00:00:00.000' AS DATETIME) AND my_date < CAST('04/01/2008 00:00:00.000' AS DATETIME)
The first method isn't very intuitive and is error-prone in my opinion. The second method kills performance since indexes can't be used and it becomes much more complex if you can have searches that span years or begin/end in the middle of months. The third method, which Rowland suggested, is the best I think.
Simply try removing the time from the date field like so:
declare #startDate varchar(20)
declare #endDate varchar(20)
set #startDate = '01/01/2008'
set #endDate = '04/01/2008'
SELECT min(date),max(date) FROM view_Inspections
WHERE CAST(FLOOR(CAST(date AS FLOAT)) AS DATETIME) BETWEEN CAST(#startDate AS DATETIME) And CAST(#startDate AS DATETIME))
This will return everything from 01/01/2008 00:00:00 to 04/01/2008 11:59:59.999.
If you don't want 04/01 included, change your end date to 03/31/2008.
Your best solution is just create a BIGINT(10) field that called "julian", and store it in YYYYMMDD.
Then do the query
where julian >= '20120103' AND julian <= '20120203'