Given a date range, find events that overlap within that range - c#

Given a input date range, such as 11/1/2015 - 11/15/2015, what is the most efficient way to determine which events(CalendarEvents) are going on during that given date range.
event eventStart eventEnd
==================================
expo 10/25/2015 11/4/2015 //This should be selected.
concert 11/4/2014 11/5/2015 //This should be selected.
exhibit 11/15/2015 12/1/2015 //this should be selected.
display 10/26/2015 10/29/2015 //this should NOT be selected.
Linq or SQL server would be awesome. Basically given a date range, find events that overlap within that range.
I know I could "brute force" with a bit of code, just wondering if I'm missing something more elegant?

You can use StartA <= EndB AND EndA >= StartA to get the overlapping dates:
DECLARE #startDate DATE = '20151101',
#endDate DATE = '20151115'
SELECT *
FROM CalendarEvents
WHERE
eventStart <= #endDate
AND eventEnd >= #startDate
SQL Fiddle
Reference

Related

Filter datatable between two dates

I have a column within my database called "Month". What i want to do is filter the table between two months. Example of this is March - June. I have code which works BUT only works alphabetically
string strquery = "select * from tbl_DR_data ";
string strq2 = "where";
if (DropDownList6.SelectedItem.Text != "All" && DropDownList8.SelectedItem.Text != "All") {
string month1 = DropDownList6.SelectedItem.Text.ToString();
string month2 = DropDownList8.SelectedItem.Text.ToString();
strq2 = strq2 + "[Month] BETWEEN'" + month1 + "'AND'" + month2 + "'";
}
When DropDownList6 = March and DropDownList8 = June. Nothing appears in the gridview which im binding BUT if the swap them around so DDL6= June and DDL8 = March it works :S
Is there a work around so that i can have the months ordered in how the months are meant to be instead of being alphabetical
why are you really storing months as strings in the database?, if you follow that path, trust me you are even going to encounter much more serious problems down the road & they will be a hell to debug. You can always get the month part from any date or dateTime column value.
try this code, Hope this what you expected
SET #FromMonth = 'March'
SET #ToMonth = 'June'
SELECT
*
FROM
tbl_DR_data
WHERE
DATEPART(mm,CAST([Month]+ ' 1900' AS DATETIME)) >= DATEPART(mm,CAST(#FromMonth+ ' 1900' AS DATETIME))
AND DATEPART(mm,CAST([Month]+ ' 1900' AS DATETIME)) <= DATEPART(mm,CAST(#ToMonth+ ' 1900' AS DATETIME))
This is the MSDN Syntax for BETWEEN
test_expression [ NOT ] BETWEEN begin_expression AND end_expression
Why no results when When DropDownList6 = March and DropDownList8 = June?
With above values, your query becomes like
[Month] BETWEEN 'March' AND 'June'
Unfortunately, when you are filtering using BETWEEN, begin_expression should be less than or equal to end_expression. In your case, since you have stored months (names) as string in the database, March comes after June in alphabetical order and so above condition returns false and no results.
This is a fiddle example same as yours with no results.
You can get the month from a date/datetime field using various methods. In sql server, you can use;
//Month NUMBER
month(datefield) as month_Number
//Month NAME
datename(month,datefield) as month_Name
Just to give you worst side of your design. Just check the results of filtering by where month between 'april' and 'may'.
Your results include: August, December, February, January, July, June, March
Solution:
For the time since you don't have full date, I guess it would be better to update your database filed as below and change the datatype of [month] to int type;
update yourTable
set [month] = case [month] when 'January' then 1
when 'February' then 2
...
when 'December' then 12 end
Now change the data type of [month] to int type and then pass the month number from the code as
[month] BETWEEN 3 and 6
Also, try to avoid key words such as Month for field names.
I am not sure what your DB design is or even what the Month Fields data-type is, I agree with other first & foremost that this is not a good design as i cant think of a scenario where i can search only based on month. This should be a complete date fields.
It can give us better idea if you give us very brief about this functionality like where you want to use it & purpose.
Please don't take me as a critic... more details about your project can help us better understand & recommend solution. May be i am wrong as i may have not understand your question.
You can use nice solution given but think for the road ahead..

How do I perform date-part comparison in EF

i heard people saying date time comparison do not work just due to time part because datetime has time part.
in sql i always compare datetime like this way and it works fine
select * from employee
where convert(varchar,dob,112) > '20111201' // this yyyymmdd format.
how could i simulate this in a LINQ query?
If you're using .NET 4 or above, just use the EntityFunctions.TruncateTime helper method. This will translate this type of datetime-to-date conversion to SQL for you.
from e in EfEmployeeContext
where EntityFunctions.TruncateTime(e.DOB) > new DateTime(2011,12,01);
The one thing to keep in mind is that operations on DateTime structs that represent database columns don't translate to SQL. So, you cannot write a query like:
from e in EfEmployeeContext
where e.DOB.Date > new DateTime(2011,12,01);
... because e.DOB represents the DOB column in the database, and EF won't know how to translate the Date sub-property.
However, there's an easy workaround depending on what dates you want:
If you want to include all employees that have a DOB on 12/01/2011 as well as those born after that date, then simply query:
from e in EfEmployeeContext
where e.DOB > new DateTime(2011,12,01);
If you want to include only employees born after 12/01/2011, then query:
from e in EfEmployeeContext
where e.DOB >= new DateTime(2011,12,02);
In short, the criteria, meaning a constant or literal DateTime you're comparing against, can be set up however you want. You just can't make radical modifications to properties that represent DB columns within the where predicate. That means you can't compare one DateTime column to a projection of another DateTime column, for instance:
//get all employees that were hired in the first six months of the year
from e in EfEmployeeContext
where e.HireDate < new DateTime(e.HireDate.Year, 7, 1);

How to assign yesterday's date to a parameter C#

I have a C# program that will run as a windows scheduled task. This program will load, run a SQL Query, email the results stored in the dataset, and then close. I have everything except the using Yesterdays date.
Here is my current Query:
SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, #startdate AS Start, #enddate AS Today
FROM Paid_Out_Tb
WHERE (Store_Id = 1929) AND (Paid_Out_Datetime BETWEEN #startdate AND #enddate)
Obviously I need to assign #startdate and #enddate at the time of the query. Since I will need 12AM to 1159PM that is the reason for the start and end. So for example. If I want to run the program today it would search yesterday (the 23rd) so #startdate would be assigned 7/22/12 00:00:00 and #enddate would be assigned 7/22/12 23:59:59...
Would it make more sense to do it in the query instead of the program? If so how would I change the query?
Slight improvement on the existing answers, to always get the start of yesterday without having to call the DateTime constructor.
var todayStart = DateTime.Today;
var yesterdayStart = todayStart.AddDays(-1);
var yesterdayEnd = todayStart.AddSeconds(-1); // Ick...
Note that this will use the current system time zone for the meaning of "today" - are you sure that's what you want? You may wish to consider using:
var todayUtcStart = DateTime.UtcNow.Date;
...
It's a shame that BETWEEN treats the end point as inclusive - if it were equivalent to
start <= value && value < end
then you could just give two midnight values, which would be a lot clearer.
Also note that while it wouldn't make interacting with the database any cleaner, for other uses of dates and times, you may wish to consider my Noda Time library, which contains a data type specifically for representing a date (and another for "time of day") etc. The aim is certainly to clarify code using dates and times. If it doesn't, I've failed!
You could calculate the start of yesterday in C#:
var yesterday = DateTime.Now.AddDays(-1);
var startOfYesterday = new DateTime(yesterday.Year, yesterday.Day, yesterday.Month);
com.Parameters.AddWithValue("#enddate", startOfYesterday);
If you're using SQL Server 2008+, you can change the datatype from datetime to date. The later can only store dates, so you won't have to worry about the datetime part.
Don't use between when dealing with date intervals. It is much easier and safer to use >= and <.
Something like this will give you yesterday stuff without parameters.
SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, #startdate AS Start, #enddate AS Today
FROM Paid_Out_Tb
WHERE Store_Id = 1929 AND
Paid_Out_Datetime >= dateadd(day, datediff(day, 0, getdate())-1, 0) and
Paid_Out_Datetime < dateadd(day, datediff(day, 0, getdate()), 0)
I assume you all looking for something this way
DateTime yesterdDaysDateTime = DateTime.Now.AddDays(-1);
You should always use parameterized queries.
In order to support what you are looking for you can drop in yesterdays date into a variable and pass that variable to your parameter.
This might also work, however with a performance drawback:
DateTime yesterday = DateTime.Today;
Thread.Sleep(1000 * 60 * 60 * 24);
You can also do this in SQL:
SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment,
Paid_Out_Datetime, Update_UserName, Till_Number, #startdate AS Start, #enddate AS Today
FROM Paid_Out_Tb
WHERE (Store_Id = 1929)
AND (Paid_Out_Datetime BETWEEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
AND dateadd(second, -1, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE()))))
If you want to put in the query itself:
select (date_trunc('day', NOW()) - INTERVAL '1 day'); -- Yesterday Start
select (date_trunc('day', NOW()) - INTERVAL '1 second'); -- Yesterday End

Compare date if there is a date in the database

I have a simple LINQ query. I would like to only check the DateDisable if there is an entry in the database. If the user doesn't select a date to disable the entry will always show. Can someone please show me how to add a conditional statement within linq
return (from promo in context.Promoes
where promo.DateEnable <= DateTime.Today
where promo.DateDisable >= DateTime.Today
orderby promo.SortOrder
select promo).ToList();
Given that DateEnable is a DateTime?, you can do the following:
// Get today.
DateTime today = DateTime.Today;
return (
from promo in context.Promoes
where
promo.DateEnable <= today &&
(promo.DateDisable == null || promo.DateDisable >= today)
orderby promo.SortOrder
select promo
).ToList();
Basically, you need to check for null or whether or not the date is greater than today.
Also you should capture the value outside of the statement, it's not guaranteed that the the LINQ provider will translate DateTime.Today on the database side correctly.
However, be warned that because of deferred execution, if you wait a long time to execute the query, today might not give you the value you expect (if the time between declaring the query and executing it rolls past midnight).
Of course, if your database server is in a different timezone than your application server, then you'll need to ensure that DateTime.Today is handled by your LINQ provider correctly (so that it's executed on the server) and use that if you want to compare against time on the DB server. If your provider doesn't handle translating DateTime.Today correctly, then you'll have to resort to a stored procedure and call that.

Linq to Entity get a Date from DateTime

var islemList = (from isl in entities.Islemler where (isl.KayitTarihi.Date >= dbas && isl.KayitTarihi.Value.Date <= dbit) select isl);
It gives error: date is not supported in LINQ to Entities...
How can i get date in linq.
Use EntityFunctions.TruncateTime.
if KayitTarihi is a date column in DB (and dbas and dbit are DateTime), use:
var islemList = (from isl in entities.Islemler where (isl.KayitTarihi >= dbas && isl.KayitTarihi <= dbit) select isl);
The .Date property is not supported in Linq to Entities (though it may be supported in other implementations of Linq).
I realize that you only want to compare the dates, but there is no real problem with comparing the datetimes if the dbas and dbit values are datetimes with time 00:00:00.
You might have to offset the dates or use other inequality checks to get the proper interval but the comparison will work as you intend.
I would personally go with Jandek's solution.

Categories