Query Datetime Declaration - sql

I'm having trouble with a Datetime column in a table while adding declaration on a stored procedure.
I want to set #EventTime as a day of the week without modifying the column..
More like a catch.
For example:
declare #EventTime datetime
set #EventTime = (select EventTime
from _LogClients
where ClientID = #ClientID)
if (#EventTime like '%2-2%) -- As a day of a week not as a numerical date.
- - Datetime preview:2019-01-22 17:47:00
Any help regarding that matter?
Note:
The EventTime is used on a Stored Procedure which runs on a certain event that occur.. However, the database is a Game one, so the logger is based on the server files, I need to know if I'm able to make the EventTime declaration able to read the datetime from the column as weekday in order to execute a certain query for that day (Not SQL Agent based though.. that's a different story).

I'm not sure from your question if you are trying to get the numerical representation of the actual day of the week (like Sunday would be "1", Monday as "2", etc.. ) or if you just need the day of the week as a word from a date.
Here is your code modified to use the word for the day of the week (please note you could have used the DateName within the select statement but then you'd need to change the type of #EventTime to a nVarchar() or nchar) :
declare #EventTime datetime
set #EventTime = (select EventTime
from _LogClients
where ClientID = #ClientID)
if (DATENAME(dw,#EventTime) like '%Tuesday%)
If you wanted the numerical equivalent use:
if (DATEPART(dw,#EventTime) = '1' -- Testing for Sunday day name

Related

Is it possible to give the DATEADD function a variable as argument that stores either DAY, WEEK, YEAR, etc.?

What I'm trying to do is declare a variable INTERVALSTART which is the start of an interval of a query. This variable is based on the current date (INTERVALEND), reduced by the desired number of weeks, months, years, etc. I want to input this variable into the DATEADD function as an argument.
An example: I would like to run the query with the interval of the last three weeks. The query then 'gets' the information I would like it to return.
DECLARE #PERIOD_TYPE VARCHAR = 'WEEK'
DECLARE #PERIOD INT = 2
DECLARE #INTERVALEND DATE = GETDATE()
DECLARE #INTERVALSTART DATE = DATEADD(#PERIOD_TYPE, -(#PERIOD), #INTERVALEND)
The code above does not work, but it is what I would like to achieve. DATEADD does not work when I give it a VARCHAR as argument.
Is it possible? Thanks in advance

SQL query based on two values in a column with a date range

So here is what I'm attempting to accomplish. I want to have returned all rows within a specified date range where the value in a column is one value 'C' or another 'X'. I'm not huge in SQL and much more comfortable in scriptwriting for excel or google sheets. I would assume there's a pretty simple solution but here is what I have written so far that's not working.
Declare #FromDate DateTime
Declare #ToDate DateTime
Set #FromDate='20201027'
Set #ToDAte ='20201102'
select * from oehdr where OrderStatus='C' or OrderStatus='X'
The errors I've received have been "Invalid SQL, No Memory" and a script error when I modify the current attempt.
There's not enough info in the question. We don't know the name of the date column, or whether the time is included, or whether the ToDate value is inclusive of the whole day. It's not even 100% clear exactly what DB you're using, as there's some conflicting info with the question.
But I'll do the best I can making some guessues:
Declare #FromDate DateTime = '20201027'
Declare #ToDate DateTime = '20201102'
SELECT *
FROM oehdr
WHERE OrderStatus IN ('C', 'X')
AND OrderDate >= #FromDate AND OrderDate < DATEADD(day, 1, #ToDate)
Notice I did not use the BETWEEN operator. BETWEEN is inclusive at both ends of the range, which is rarely what I want for dates. Instead, when I want the full day, I add one day and use an exclusive condition for the end of the range.

SQL Server end of month

Suppose there is one date in int format 20191229, I want to find end of month and check if it's end of month is of 31 days or 30 days in SQL Server
You can try this from the reference. The given answer will not work for the integer data type but it will work in the varchar datatype date value. Storing Date values in integer is not a good idea, so as suggested by Larnu change the data type in either date or varchar.
SELECT
Day(EOMONTH(Cast('20191229' as Date))) end_of_month;
If you want the amount of days within a month, as you need the days as an integer, you should go for this. This is the most robust built, but also the more complex one, as to make sure the Integer value is processed correctly:
SELECT DATEPART(DAY,EOMONTH(CAST(CAST('20191229' AS NCHAR(8)) AS DATE))) AS Days
Result:
Days
31
If you want to add an IF evaluation to your selected date(s), you can do this by add an IIF-clause where it evaluates whether or not the end of month is 31 or not. If you want to use a columnname instead of the date, just substitute #Date with the columnname. I've just added the variable #Date instead of '20191229' to make it more illustrative/understandable. You can change the True/false descriptions to whatever you like in the query.
DECLARE #Date AS int
SET #Date = '20191229'
SELECT
IIF (
DATEPART(DAY,EOMONTH(CAST(CAST(#Date AS NCHAR(8)) AS DATE))) = '31'
,'True'
,'False'
) AS Days
Output:
Days
True

SQL Server: compare dates by only matching month and day

I have a stored procedure that fetches records based on dates matching a date input which works fine so far.
Both the dates in the table and my input date are formatted as datetime.
Instead of comparing the full dates I would like to change this so that it only compares month and day so that it works with any year for the input.
Example:
A date in the table is saved as 2013-04-30 and my input date is 2014-04-30.
What I want is that the stored procedure still returns that record independent of the year as long as month and day match.
My stored procedure:
ALTER PROCEDURE [dbo].[FetchDays]
#inputDate datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT dateID,
dayDT,
countries,
regions
FROM DaysDT
WHERE dayDT = #inputDate
FOR XML PATH('daysFixed'), ELEMENTS, TYPE, ROOT('root')
END
Many thanks for any help with this, Mike.
You can do something like this ;)
ALTER PROCEDURE [dbo].[FetchDays]
#inputDate datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT dateID,
dayDT,
countries,
regions
FROM DaysDT
WHERE
DAY(dayDT) = DAY(#inputDate) --Extract and compare day
AND MONTH(dayDT) = MONTH(#inputDate) --Extract and compare month
FOR XML PATH('daysFixed'), ELEMENTS, TYPE, ROOT('root')
END
Try this:
WHERE datepart(day, dayDT) = datepart(day,#inputDate)
AND datepart(month, dayDT) = datepart(month,#inputDate)
This will compare the date and month parts of your overall date, without checking the year.
I have been needed this type of requirement in past. I have used this solution and it worked for me as I wanted.
SELECT * FROM yourTableName
WHERE DATE_FORMAT(yourColumnName, '%m-%d') = DATE_FORMAT('yourValue', '%m-%d') and yourOtherCondition;

Creating a list of all the dates between a range and then insert it

I have a problem were I need to insert a set of dates (one row for each date) that come from a date range that comes in to me as an ical format. I also need to insert the date if the date does not exist.
I'm happy manipulating the date formats so converting the incoming 20131201T000000 to smalldatetime is ok and I can build the SQL Not Exits as separate bits but how do I go about listing all the dates between 20131201 and 20140101 and then go about inserting them into the table if Not Exists along with some other data.
One idea I had would be to count the days using DateDiff which will give me a total number of days in the range and then I could DateAdd one day at a time and insert for each date until the DateDiff total is reached. However, it seems to be that its a very messy and long winded way to go about it and I would find it challenging to say the least.
Is there another method that someone could walk me through or point me in the right direction of?
In my opinion you are much better off letting SQL Server determine the set of dates that are missing than to create a set of dates, then pull back all of the existing dates in the table to compare them to your set, then insert the ones that don't match. By doing this you are taking what SQL Server is really, really good at, tossing it in the mud, and re-inventing a wheel that is now quite non-circular.
So I suggest you do this in SQL Server.
Imagine you have an existing table with some dates:
CREATE TABLE dbo.MyTable(TheDate DATE);
And it has some existing days in the specified range:
INSERT dbo.MyTable(TheDate) VALUES
('20131203'),('20131205'),('20131209'),('20131230');
You can easily derive a set without using loops as follows.
CREATE PROCEDURE dbo.GenerateDates
#start CHAR(17),
#end CHAR(17)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #s DATE = LEFT(#start, 8), #e DATE = LEFT(#end, 8);
DECLARE #d SMALLINT = DATEDIFF(DAY, #s, #e);
;WITH x(d) AS
(
SELECT TOP (#d) DATEADD(DAY, number, #s)
FROM master..spt_values
WHERE type = N'P' ORDER BY number
)
-- INSERT dbo.MyTable(TheDate)
SELECT d FROM x WHERE NOT EXISTS
(SELECT 1 FROM dbo.MyTable WHERE TheDate = x.d);
END
GO
Sample usage:
EXEC dbo.GenerateDates
#start = '20131201T000000',
#end = '20140101T000000';
When you are happy this is giving the output you expect, alter the procedure and uncomment the INSERT.
(Also it would be best if you just pass date values from your app, instead of these 17-character strings, but I was working with what you have.)
Well lets see. You have a date called beginDate and date called endDate. Lets get all they days between those dates into list:
List<DateTime> betweenDates = new List<DateTime>();
var currentDate = beginDate;
while(currentDate <= endDate)
{
betweenDates.Add(currentDate);
currentDate = currentDate.AddDays(1);
}
Then lets fetch all the rows that are already in database:
// var datesInDb = SELECT DATE FROM TABLE_X WHERE DATE BETWEEN (beginDate, EndDate);
Now we have dates from database and all the dates that should be in database. Lets substract dates from database from our betweenDates
var datesWhichShouldBeInsertedIntoDB = betweenDates.Any(day => datesInDb.Contains(day) == false);
then insert datesWhichShouldBeInsertedIntoDB