SQL query to extract number of dates in the same month - c#

I want to write a SQL command that selects from database the number of rows in which the date has the same year and month as this year and month.
For example: it's July 2020 now, so I want the command to extract the no. of rows in which the dates lie in July 2020.
From what I have understood on the other answers from Stackoverflow, I wrote this C# code:
cmd = new SqlCommand("SELECT COUNT(date) FROM ordertbl WHERE MONTH(date) = MONTH(GETDATE()) AND YEAR(date) = YEAR(GETDATE())", con);
dr = cmd.ExecuteReader();
dr.Read();
lblthismonth.Text = dr[0].ToString();
dr.Close();
The column with the date is called date.

It would be better not to manipulate your table data. Search a calculated range instead:
SELECT COUNT(date)
FROM ordertbl
WHERE
date >= CAST(DATEADD(DAY, 1, EOMONTH(GETDATE(),-1)) AS DATE) and
date < CAST(DATEADD(DAY, 1, EOMONTH(GETDATE())) AS DATE)
With your query, if you have a million rows, and 100,000 of them match, sqlserver must do 2 million date operations to extract the year and month from the million dates, and then 2 million comparisons comparing the extracted numbers. An index can not be used
If you work out a date range, and the column is indexed, then sqlserver can use the indexed data because it isn't being manipulated, and know which 100,000 rows to retrieve. In the case of a Count like this it doesn't even need to hit the table; it can just count the index
Typically we should always try to avoid putting a function call on the left hand side of a comparison operator in a WHERE clause

Related

Store DayOfWeek data in SQL Server

I want to save the DayOfWeek data as a column in a SQL Server table. Is this possible? ATM I'm saving an int and converting to DayOfWeek with a switch method, but I wish I could save and retrieve the data directly from the database.
UPDATE
I will try to explain. The user creates a recurring event, usually 2 times a week, for example, Monday and Friday. I want to create (on code run) all the recurring events in a given month, SO I want to store the DayOfWeek in SQL because for every event user can register if another user were present, late or so on..
Here a part of the code:
public static List<int> GetAttendance(int year, int month, DayOfWeek doW_1, DayOfWeek doW_2)
{
var days = DateTime.DaysInMonth(year, month);
var attendances = new List<int>();
for (int currentDay = 1; currentDay <= days; currentDay++)
{
var day = new DateTime(year, month, currentDay);
if (day.DayOfWeek == doW_1 || day.DayOfWeek == doW_2)
{
attendances.Add(currentDay);
}
}
return attendances;
}
doW1 and 2 comes from a little converter method made by me who read in db the integer stored by the user to create the recurring events.
UPDATE 2: I want to store data this way because I will use them for PREDICT future events by user inputs. Clear now?
You have two options.
Store your date value in a Date or DateTime columns and when querying, write queries with a where clause something like
WHERE DATENAME(WEEKDAY, DateColumn ) = 'Sunday'
But this will not be a sargable expression and on bigger data sets the query performance will be bad.
You can also store the week day in a Varchar(9) column and again use DATENAME() to extract the Week Day name from your date values at the time of Insert/update.
You can index this column and write simple queries like
SELECT * FROM Table
WHERE DateColumName = 'Sunday'
This option is commonly used in data warehouse environment where reducing data redundancy is not the goal but best read performance is the goal.
Keep storing it as an int, but you can get rid of your switch by just casting your saved int like so:
DayOfWeek day = DayOfWeek.Friday;
int temp = (int)day;
day = (DayOfWeek)temp;
Console.WriteLine(day); // Friday
Save it as a Date Column and use the following SQL functions to parse the WeekDay ID or WeekDay Name.
Using a date keeps your data structure understandable.
SELECT Datepart(weekday, Getdate())
SELECT Datename(weekday, Getdate())

Update 2 million rows for 1 column

I have a table with approximately 2 million records. I have to loop through each record and update the effective date. I need to set the day to the first of the month for each date.
If the current date is the first of the month, then ignore.
i.e.
07/01/2018
07/21/2018 => 07/01/2018
08/11/2018 => 08/01/2018
Currently, I'm writing this as a C# program and it taking way too long.
Is there a better solution?
Just use DATEADD() and DATEDIFF() combination to get the first of the month date
UPDATE t
SET datecol = DATEADD(MONTH, DATEDIFF(MONTH, '1900-01-01', datecol), '1900-01-01')
FROM yourtable t;
It could be as simple as:
Update myTable
set myDate = DateAdd(day, 1-Day(myDate), myDate)
where day(myDate) > 1;

Using sql to add to dates during a query

I have a table that keeps track of when particular events occur, and how long they last. For reasons I cannot fathom, it was designed to store the start date of the event, start time of the event, then the number of hours and minutes the event lasted. Like this:
EventStartDate | EventStartTime | TimeSpentHours | TimeSpentMinutes
Where EventStartDate is a dateTime with the hours/minutes always set to zero, so that, even though it's a date time, all the values are like "12/22/2016 00:00". The EventStartTime is a char(4) which is military time of the start of the event. TimeSpentHours is and int which is the total hours the event duration, and TimeSpentMinutes is an int for the number of minutes. Obviously the total time spent for the event is the hours plus the minutes.
The problem: I need to be able to, given a particular DateTime, find all the events that were occuring during that time. Put another way, given a particular DateTime I need to get all the events with a starting date and time that's greater than or equal to the given DateTime and less than or equal to an "end" date and time.
So I need to compute the "EndDateTime" based off the values in the database during the query. The database is SqlServer 2008 R2. I am using C# for WinForm application to query the data.
So far I have roughly:
public static List<ImportantEvents> GetEventsDuringDateTime(DateTime timeOfEvent)
{
using (SqlConnection sqlConn = getAndOpenSqlConn())
{
string theEventTime = timeOfEvent.ToString("hhmm");
string sqlStmt = "SELECT EVENT_ID, AGENCY, EVENTSTARTDATE, ACTNOTE, EVENTSTARTTIME, TIMESPENTHOURS, TIMESPENTMINUTES FROM EVENTSMAIN WHERE((EVENTSTARTDATE<= #MYEVENTDATETIME AND EVENTSTART TIME< #ACTTIME) AND ...";"
}
}
(the above SQL obviously won't work and is where I am stuck...)
My question is: how can I, in the query, add the EVENTSTARTTIME to the EVENTSTARTDATE to create a new "temporary" column, then add the TIMESPENTHOURS and TIMESPENTMINUTES to that column into another new "temporary" column, to then query against given a specific DateTime value???
It is possible to achieve this in a single query with a common-table expression like this:
With StartAndEndTimes As (
Select Event_ID,
EventStart = DateAdd(Minute, Convert(int, Right(EventStartTime, 2)), DateAdd(Hour, Convert(int, Left(EventStartTime, 2)), EventStartDate)),
EventEnd = DateAdd(Minute, Convert(int, Right(EventStartTime, 2))+TimeSpentMinutes, DateAdd(Hour, Convert(int, Left(EventStartTime, 2))+TimeSpentHours, EventStartDate))
From EventsMain)
Select Event_Id, EventStart, EventEnd, <<add other fields here>>
From StartAndEndTimes
Where EventStart <= #MyEventDateTime
And EventEnd > #MyEventDateTime;
Basically you can extract the hours and minutes from the start time and add them to the start date to get a true, datetime, start date. Similar with the end date. It is not necessary to use common-table expression here, but it does make the code more readable. Then you just do the ordinary date comparison to your input parameter.
Here I have disected parts of the final query. You will need to put the final part into your query wherever you need it.
SELECT Combined = EVENTSTARTDATE + EVENTSTARTTIMEFROM FROM EventsMain
SELECT CombinedWithHour = DATEADD(hh, TIMESPENTHOURS, Combined) FROM EventsMain
SELECT CombinedWithMinute = DATEADD(mi, TIMESPENTMINUTES, CombinedWithHour) FROM EventsMain
All together:
SELECT DATEADD(mi, TIMESPENTMINUTES, DATEADD(hh, TIMESPENTHOURS, EVENTSTARTDATE + EVENTSTARTTIME)) FROM EventsMain

RowFilter expression of DataTable for subtracting two dates

Can anyone correct my RowFilter expression to subtract two dates where one date is database table column and other date is current date. Below is my code snippet where i am checking whether difference between the dates is less than or equal to 10."CreationDateTime" is database table column.With this code i am getting missing operand error.
dataQuery = string.Format("(CreationDateTime - (" + DateTime.Now + "))<={0}",10);
myDataView.RowFilter = dataQuery;
One option might be create another column (creating another column in your query) for the difference hours between them and creating a filter after that.
You can use DATEDIFF to get's difference current date and return int as an hour like;
DATEDIFF(hh, CreationDateTime, GETDATE()) as HourDiff
and you can filter that in your DataTable like;
myDataView.RowFilter = "HourDiff <= 10";

Search data only day value of date

Is it possible to search a data by day or month value of a date type value in mysql and c#.net.please can any one help me?
You can use DAY and MONTH functions:
SELECT *
FROM yourtable
WHERE DAY(date_column) = 1
or
SELECT *
FROM yourtable
WHERE MONTH(date_column) = 1
have a look at MySQL date and time functions.

Categories

Resources