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
Related
My goal is to query the database for entries of the current day. Let's say the user saves a row with a time of '2021-01-27 01:00' and one with '2021-01-27 00:59'. The time zone is GMT+1 so it will be stored in the database in UTC like this:
row1: '2021-01-27T 00:00Z'
row2: '2021-01-26T 23:59Z'
How can I query for rows of the 27th of January 2021 (selectedUtcDate), from the view of the client / client?
The following will only return one entry:
.Where(row => row.Date == selectedUtcDate)
Do I have to use a range to get all entries of the same date?
.Where(row => row.Date >= selectedUtcDate && row.Date < selectedUtcDate.AddDays(1))
Or is this even automatically resolved by entity framework?
This has nothing to do with a database. The problem is, that the 24 hours or January 27th in Beijing are not the same 24 hours in Greenwich.
Internally, you use UTC. If somewhere on a computer in Beijing a date in local time is known, you know the start DateTime of that day and the start DateTime of the next day. After that you can convert these DateTime value to UTC:
DateTime localDay = FetchDateInLocalTime(); // The day in Beijing
DateTime utcDayStartTime = localDay.Date.ToUniversalTime;
DateTime utcNextDayStartTime = utcDayStartTime.AddDays(+1);
Now comes the database part:
var result = dbContext.Orders.Where(order => utcDayStartTime <= order.Date
&& order.Date < utNextDayStartTime);
Simple comme bonjour!
So to answer the original question with help of the comments:
Yes you have to use a range to query dates like this.
And of course you need to use the client's local date converted to utc (or the offset) as Harald Coppoolse mentioned.
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
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..
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.
I have this query:
SELECT who,whenAT
FROM seen
WHERE whenAT <= Datetime('now', '-5 minutes')
DateTimes stored in whenAT are formatted like this "10/12/2011 12:33:13 AM" whenAT is a TimeStamp.
that current query returns all records for some reason.
i'm inserting the datetime from code as DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") this is what is being saved into the table "10/12/2011 12:33:13 AM" i want to get all records within the last 5 minutes. everything i have tried either returns all records or no records.
Your query should be
SELECT who,whenAT FROM seen WHERE whenAT >= Datetime('now', '-5 minutes')
To get the last 5 minute, < will get everything besides the last 5 minutes
as Fatal510 said, you need to add the modifier 'localtime'
here some reference about datetime modifier https://www.sqlite.org/lang_datefunc.html
and here some example
SELECT who,whenAT FROM seen WHERE whenAT >= Datetime('now', '-5 minutes', 'localtime')
needed to add the modifier 'localtime'