Selecting records where 'ActualLiveDate' is between today and X days in to the future with SQL Server - sql

I'm trying to get the syntax to show a list of records where the Actual Live Date is equal to or greater than today by 7 days and ideally show how many per day (thursday = 7 records).
i was thinking something along the lines of:
SELECT [PW Number]
,[status]
,[install Date]
,[ICL Client Code]
,[Actual Live Date]
FROM
[QuoteBase].[dbo].[Circuits]
WHERE
[Actual Live Date] BETWEEN today and 7 days time (this is where I am a little stuck as im fairly new)

If you need "today" to start at 00:01 this morning, then you need to remove the time portion from e.g. GETDATE(). I'm also using explicit functions to show that I'm adding days:
SELECT [PW Number]
,[status]
,[install Date]
,[ICL Client Code]
,[Actual Live Date]
FROM
[QuoteBase].[dbo].[Circuits]
WHERE
[Actual Live Date] BETWEEN
DATEADD(day,DATEDIFF(day,0,GETDATE(),0) AND
DATEADD(day,DATEDIFF(day,0,GETDATE()+7,0)
If Actual Live Date contains a time component, you may want to adjust the +7 to +8, depending on exactly which rows should be included in the result or not.

you can use the BETWEEN and GETDATE() functions for this, the GETDATE() + 7 will add 7 days onto todays date
SELECT [PW Number]
,[status]
,[install Date]
,[ICL Client Code]
,[Actual Live Date]
FROM
[QuoteBase].[dbo].[Circuits]
WHERE
[Actual Live Date] BETWEEN GETDATE() AND GETDATE() + 7

If the column is actually a date, you need to be a bit careful:
[Actual Live Date] BETWEEN cast(GETDATE() as date) and cast(GETDATE() + 6 as date)
This would include today. If today is a Monday, it would include seven days up to next Sunday. If you would want next Monday too, then the -6 would be -7.
When the column is a date, The comparison [Actual Live Date] >= getdate() will always be false for dates today because of the time component.
Between works as expected for datetime values but not for date values.

Related

WTD this year compared to WTD last year

I would like to determine the growth on sales data from current year WTD with sales data from the same week last year also WTD.
So if this week is Mon, Tue, Wed I am trying to compare Mon, Tue, wed from the same week last year to determine the sales growth. This needs to be dynamic in a sense since it will be running on a daily report, ending WTD on the previous day, through SSRS which will be emailed to various users.
I have done copious amounts of online searching and tried several iterations, all with undesirable affects.
The latest attempt being
SELECT
[storeid],
SUM([Sales]) as [2021SalesWTD]
FROM [dbo].[DailySales2021]
WHERE CONVERT(date, [date]) >= DATEADD(DAY, 1-DATEPART(dw, DATEADD(YEAR,-1,GETDATE())), CONVERT(date, DATEADD(YEAR,-1,GETDATE())))
AND DATEADD(DAY, 8-DATEPART(dw, DATEADD(YEAR,-1,GETDATE())), CONVERT(date, DATEADD(YEAR,-1,GETDATE())))
GROUP BY storeid
This returns the entire week
It might help you to try variable declarations.
Here's something I've drafted up:
--Get today's date, find the day of the week (1 indexed from Sunday) and subtract. Add 2 to balance this offset
DECLARE #MondayThisYear AS DATE = CAST(GETDATE()-DATEPART(WEEKDAY, GETDATE())+2 AS DATE)
--Get the date a year ago. I haven't checked for leap year, add it if you need it
DECLARE #DateLastYear AS DATE = #MondayThisYear-365
--Same idea as MondayThisYear, but using the date from last year
DECLARE #MondayLastYear AS DATE = CAST(#DateLastYear-DATEPART(WEEKDAY, #DateLastYear)+2 AS DATE)
--The number of days that have passed in this working week
DECLARE #WorkingDays AS INT = DATEDIFF(d, #MondayThisYear, GETDATE())
SELECT [insert columns]
FROM [insert table name]
WHERE ([date column]>#MondayThisYear AND [date column]<GETDATE()) OR
([date column]>#MondayLastYear AND [date column]<#MondayLastYear + #WorkingDays)
You might also need to check how I've defined the previous year's dates. In worst case you might get an off-by-one week error, but I don't think that's avoidable given the structure of the calendar.

Making new column based on date with variable year

As topic is saying, it all should apply to dates with variable year.
I would like to make a new column (called which_part for example) saying if the date (in this case date is in "sil.sales_invoice_date") is between 1st of january to 30th of june - which should say H1 (half 1) and else is H2 (between 1st of july to end of the year).
I've tried doing something like that with convert
SELECT
sil.sales_invoice_date AS "Distributor Invoice Date",
CONVERT(sil.sales_invoice_date, #year + '-01-01') AS [start year],
CONVERT(sil.sales_invoice_date, #year + '-06-30') AS [end year],
It doesn't work at all and I can't write [half year] in there.
I've also tried to do it by using
case sil.sales_invoice_date between
But I don't really know how to format it to work with variable year.
if you have date in format dd.mm.yyyy
Try this
Case when substr(sil.sales_invoice_date,1,5) between '01.01' and '30.06' then 'H1'
else 'H2'
end as which_part;

Create a sql query based on selected month from dropdown combobox in excel userform

I have a userform in excel for attendance reporting. On the form the user chooses the employee they want to review, and then they can check a box that says year to date, or select individual months from a combobox drop down. This is all to query our sql server that has the data on it. Year to date is easy, because I know how to use the variables for current date and first day of the year. What I'm having trouble with is how to convert the user's month selection into a usable query. For example: If the user selects January for the drop down, the query would be
select * from [dbo.mytablename]
where [agent name] = '<value from a textbox that I know how to pass in>'
and [cal date] > '1/1/2018' and [cal date] < '1/31/2018'
Right now my only idea is to have cells on a holding spreadsheet in the workbook that have the first and last day of each month and then use the cell values. But I'd like to avoid that if possible. If you have any ideas that would be great!
First of all
and [cal date] > '1/1/2018' and [cal date] < '1/31/2018'
will select all data from Jan 1 to Jan 30 and not include any data from Jan 31.
Keeping this in mind, the check should be
and [cal date] > '1/1/2018' and [cal date] < '2/1/2018'
So if you do get a month from drop down you can do something like below
select * from [dbo.mytablename] t
join
(values
('Jan', 1),('Feb',2),('Mar', 3),
('Apr', 4),('May',5),('Jun', 6),
('Jul', 7),('Aug',8),('Sep', 9),
('Oct', 10),('Nov',11),('Dec', 12)
)v(mon,num)
on v.mon='<month name received from a text box>'
t.[agent name] = '<value from a textbox that I know how to pass in>'
and t.[cal date] > cast(cast(v.num as varchar)+'/1/2018' as date)
and t.[cal date] < cast(cast((v.num+1)%12 as varchar)+'/1/'+ cast(2018+ (v.num/12) as varchar) as date)
In SQL Server there are numerous techniques for date calculation/converions. If 2012+ you can use EOMonth() or DateFromParts().
I should also add [cal date] < '1/31/2018' should be [cal date] <= '1/31/2018'
Example
Select StrCast1 = try_convert(date,concat('January',' 1, ',2018))
,StrCast2 = EOMonth(try_convert(date,concat('January',' 1, ',2018)))
,FromParts1 = DateFromParts(2018,1,1)
,FromParts2 = EOMonth(DateFromParts(2018,1,1))
Returns
StrCast1 StrCast2 FromParts1 FromParts2
2018-01-01 2018-01-31 2018-01-01 2018-01-31
Assuming your month is a numeric value between 1 and 12, you can use something like
Dim fromDate As Date, toDate As Date
fromDate = DateSerial(2018, month, 1)
toDate = DateSerial(2018, month + 1, 1)
Debug.Print fromDate, toDate
This will work even with December, DateSerial accepts a 13 as month.
Note that you have to ask for < first day of next month to catch data from the last day of the month.
Side note: I assume you use a ADODB.Command to query the database. I would strongly suggest that you use ADODB.parameter to pass the dates (and the agent name) to the database - you don't have to deal with formatting or converting the dates so that the database understand them correctly. See for example https://stackoverflow.com/posts/10353908/edit to get an idea how this works.
Update
I assume you fill your combo box with values from a range and the value is linked to a cell. Use for example the match function to get the month as number (I would never trust that the name of a month is translated correctly by Excel or the database, there are too many things like regional settings that could cause that it breaks).
Assuming:
Range with month names: A1..A12
Linked cell: B1
Put the formula =MATCH(B1,A1:A12) in cell B2. VoilĂ , you have the number of the month.

MS Access - SQL Query for Average of Each Day Data

I have a set of data spanning across 3 days. Based on the first column from the left, is it possible to have a query that calculates the average of the values in the third column from the left based on each day?
The end result will be two columns:
1/1/2008 | 1.605
2/1/2008 | 1.59
3/1/2008 | 1.56
I think the logic will be something like in a loop:
Based on the day in the first column, if it is the same day, count the number of rows and add up the values of the third column
Use the sum of the values of the third column and divide by the number of rows to get the Average
day + 1
But how can we implement a loop in MS Access?
Here is the set of data:
Edit:
If I want to group by the date, where the day is between yesterday's 6PM to today's 6PM?
The BETWEEN clause is to check for records that are between yesterday's 18:00:00 and today's 18:00:00. Example, for 1/1/2008, the record will start from 1/1/2008 6:00PM to 2/1/2008 6:00PM. For 2/1/2008, the record will start from 2/1/2008 6:00PM to 3/1/2008 6:00PM`. So on and so forth...
I have a code snippet that checks for this:
([In process analysis result].[Date Time]) Between Date()-1+#12/30/1899 18:0:0# And Date()+#12/30/1899 18:0:0#)
But it only groups for one day before. How can I apply for the set of data?
Edit 2:
This is the query that I have done, but it is still not correct. Any idea what is wrong?
SELECT DateValue([Date Time]) As DateValue, Avg([MFR g/10min]) AS [AvgOfMFR g/10min]
FROM [In process analysis result]
WHERE ((([Date Time])>Now()-365) AND (([Operation Grade-Load]) Like "EX*") AND (([Date Time]) Between [Date Time]-1+#12/30/1899 18:0:0# And [Date Time]+#12/30/1899 18:0:0#))
GROUP BY DateValue([Date Time]);
SELECT the AVG of the value and GROUP BY the date
Your logic looks basically correct. The where clause looks off. Start with this:
SELECT DateValue(DateAdd("h", 6, [Date Time])) As DateValue,
Avg([MFR g/10min]) AS [AvgOfMFR g/10min]
FROM [In process analysis result]
WHERE [Date Time] > DateAdd("yyyy", -1, DateAdd("h", 6, Now())) AND
[Operation Grade-Load] Like "EX*"
GROUP BY DateValue(DateAdd("h", 6, [Date Time]));
I'm not sure what the BETWEEN condition is supposed to be doing. If
you want a particular date range, just use date constants.
Edit: Date/time should be offset by 6 hours as in the above edit. And a proper 1-year-back expression should be used. Not sure if current time should be shifted 6 hours too (shown); if not, just remove the DateAdd of Now().

Get yesterdays date and if Monday get weekend range

Is there a way to get yesterdays date. If the current date is monday I need three dates returned - Sunday, Saturday and Friday. Is there any way possible to accomplish this in a single query. I don't know VBA that well but if that is the only way to solve I am willing to get my hands dirty.
Select * from [Purchase Order] where MyDate = 'Yesterdays date(s)'
The WeekDay() function will tell you whether today's date, as returned by the Date() function, is Monday. Use that in an IIf() expression so that MyDate matches yesterday's date when today is not Monday, or the previous 3 dates when MyDate is Monday.
SELECT *
FROM [Purchase Order] AS p
WHERE
IIf(Weekday(Date()) = 2,
p.MyDate BETWEEN DateAdd('d',-3,Date())
AND DateAdd('d',-1,Date()),
p.MyDate=DateAdd('d',-1,Date())
);