I need to update logic to add buffer to to do data for last 24 hours instead of 7 days
DECLARE #todo = #opinion== 0? DateTime.UtcNow.AddDays( - 7) : new DateTime(#opinion);
Tried this with offset but it didn't work for me.
DECLARE #todo = #opinion== 0? DateTime.UtcNow.AddDays(-7) : new DateTimeOffset(#opinion, DateTime.UtcNow.AddHours(-24));
opinion is within the last 7 hours
DECLARE #opinion = DateTime.UtcNow.AddHours(-9);
SELECT ...
WHERE opinion >= DateTime.UtcNow.AddHours(-7) AND opinion <= DateTime.UtcNow;
Missing details for a complete answer.
Related
For the life of me, it seems I can't filter my TFDQuery using a DateTime field/format. I have this query that needs to "import" filters from a component (cxGrid), among them are:
"Date = " (DateTimeField);
"Value = " (FloatField);
"Supplier = " (StringField);
(And a few others, but those are the more important ones). Date is seconds sensitive, so it has HH:MM:SS, this is necessary for stock/contability purposes.
Now what I mean about "importing" filters is that I'm using the same filters as the ones current marked on a cxGrid. I do so using this simple method:
Filter := cxGridDBTableView.DataController.Filter.FilterText;
Which gives me a string of all the filters currently in use in that cxGrid.
I then toss this string in the filters of my query as in:
MyTFDQuery.Filtered := False;
MyTFDQuery.Filter := Filter;
MyTFDQuery.Filtered := True;
This posed a problem with Value, as we had a display format changing the float to a different format (from, let's say, 2.4 to 2,40) but this has already been fixed. Supplier and the other fields all worked like a charm, mostly because they didn't have a mask/display format.
My problem is when running the DateTime field (Date) filter, I get this error:
[FireDAC][Stan][Eval]-114. Expected []
This field has no display formats or masks of any kind.
I did try searching for this error code online, and couldn't find anything. I did try to change the format of the Date filter, seeing as many people had issues with the format. I have tried all forms of:
MyTFDQuery.Filter := 'Date = ''2021-01-01 10:00:00'''
MyTFDQuery.Filter := 'Date = {dt 2021-01-01 10:00:00}'
MyTFDQuery.Filter := 'Date = ' + Chr(39) + '2021-01-01 10:00:00' + Chr(39)
MyTFDQuery.Filter := 'Date = {CONVERT(''2021-01-01 10:00:00'', DATETIME)}
and many others that I can't recall from the top of my head, right now.
And also tried several different formats for the date... Such as:
YYYY-MM-DD
YYYY-DD-MM
DD-MM-YYYY
MM-DD-YYYY
Or even the separators for that date. I've tried ' - '; ' / '; ' . ' and the such (like 24.02.1982 instead of 24/02/1982). and kept on trying different ways to make this work, with different combinations.
When I searched about this issue online, specially in "how to filter a dataset/tfdquery by datetime", most people were being told to use different formats for the date/datetime to make it work. It seemed everyone had a different solution for this.
I'm not sure what to try anymore. Is this somehow connected to regional settings, as one search result pointed out? Where would those settings be from? The Delphi IDE? FireDAC? The DB I use? Is there something I'm missing?
Basically I want to know what format I should be using to filter my TFDQuery.
Thank you all for reading so far, any help would be highly appreciated. I hope the question is straightforward enough.
PS: I'm sorry for anything wrong I made have done in the making of this question. English is not my native language, and it's been a really long week. Thank you for the patience.
UPDATE: I've identified the error with a lot of guesswork. The milliseconds bit of the datetime is being taken into account when the filter is going to be applied to the dataset, and the cxGrid component would round the seconds (e.g changing '2021-02-01 18:05:03.822' to '2021-02-01 18:05:04').
That way, when the Date = '2021-02-01 18:05:04' would filter something, it wouldn't show up anything. It wasn't an issue with formatting, but rather with equality of datetimes.
To fix this, I followed Brian's advice and made the change:
cxGridDBTableView.DataController.Filter.DateTimeFormat := 'yy-mm-dd hh:mm:ss.zzz'
Now the millisecs are being taken from the filter, and the rounding ignored. Unfortunatelly I'm stuck on the error it gives:
[FireDAC][Stan][Eval]-118. Couldn't convert variant of type (UnicodeString) into type (Date)
Any further help would be highly appreciated.
I've found the "solution" to this problem. I simply assumed the query didn't accept the string filter with milliseconds, maybe some compatibility issues. I'm leaving this here in hopes that someone with a problem like mine can solve it fast, and maybe someone else can improve on this and make it more elegant/efficient.
I broke the string and inserted in a stringlist for easy management:
MyStringListFilters.LineBreak := ' AND ';
MyStringListFilters.Text := Filter;
This would turn a filter's string from:
((Date = ''28/09/2022 18:22:44.789'') OR (DATE = ''11/02/2019 07:18:03.122'')) AND ((Value = 2,4) OR (Value = 7,9)) AND (SUPPLIER = ''My Supplier Name Ltda'')
To:
((Date = ''28/09/2022 18:22:44.789'') OR (DATE = ''11/02/2019 07:18:03.122''))
((Value = 2,4) OR (Value = 7,9))
(SUPPLIER = ''My Supplier Name Inc'')
Now fixing the values is easy by just using a StringReplace:
While i < MyStringListFilters.Count do
if (Copy(MyStringListFilters[i], 2, 5) = 'Value') or (Copy(MyStringListFilters[i], 3, 5) = 'Value') then
StringReplace(MyStringListFilters[i], ',', '.', [rfReplaceAll]);
(When there is two or values, there will be an extra parentheses in front of the string).
Fixing the Date was a bit harder. I had to insert the string inside another string list, and break it up the same way:
//inside of the same while
if (Copy(MyStringListFilters[i], 2, 4) = 'Date') or (Copy(MyStringListFilters[i], 3, 4) = 'Date') then
begin
MyStringListDates.LineBreak := ' OR ';
MyStringListDates.Text := MyStringListFilters[i];
//it keeps on going...
Which further breaks the date string to:
((Date = ''28/09/2022 18:22:44.789'')
(Date = ''11/02/2019 07:18:03.122''))
Be aware: We have to remove the parentheses in the first filter and in the last as well if there is two or more Date filters. We also have to set things up as it was by the end of the loop. Do remember to always increment the index integer of both whiles.
//This happens inside the first while...
while j < MyStringListDates.Count do
begin
TempDate := Copy(MyStringListDates[j], 10, 19);
//This pulls the whole second, ignoring milliseconds from the DB.
MyStringListDates[j] := '((Date >= ' + QuotedStr(TempData) + ') and (Date < ' + QuotedStr(DateTimeToStr(IncSecond(StrToDateTime(TempData)))) + '))';
FixedDate := FixedDate + MyStringListDates[j];
if FixedDate = '' then
begin
// Puts the first parentheses back.
if MyStringListDates.Count > 1 then
FixedDate := '(';
FixedDate := FixedDate + MyStringListDates[j];
end
else
FixedDate := FixedDate + ' OR ' + MyStringListDates[j];
Inc(j);
end
//Remember to add the last parentheses here, if there is more than 1 Date Filter.
I would like to thank #Brian for their help with this solution. I didn't notice the component could be changed so the DateTime would come differently.
I would also like to thank #marc_s for editing the original question. This is my first question on the platform ever, so I didn't know what I was doing (Still don't. Sorry).
Also a special thanks to #Uwe Raabe, I've also used their answer on how to split strings using a multiple character delimiter on this problem. Here's the link to that question they answered:
How to split string by a multi-character delimiter?
This is the problem. Create a trigger named trg_late_return that will write the correct value to DETAIL_DAYSLATE in the DETAILRENTAL table whenever a video is returned. The trigger should execute as a BEFORE trigger when the DETAIL_RETURNDATE or DETAIL_DUEDATE attributes are updated. The trigger should satisfy the following conditions:
If the return date is null, then the days late should also be null.
If the return date is not null, then the days late should determine if the video is returned late.
If the return date is noon of the day after the due date or earlier, then the video is not considered late, and the days late should have a value of zero (0).
If the return date is past noon of the day after the due date, then the video is considered late, so the number of days late must be calculated and stored.
Here is my code so far. It's giving me a syntax error, specifically on where I have '12:00:00'. Please help me.
delimiter //
CREATE TRIGGER TRG_LATE_RETURN
BEFORE UPDATE ON DETAILRENTAL
FOR EACH ROW
BEGIN
IF NEW.DETAIL_RETURNDATE IS NULL THEN
SET NEW.DETAIL_DAYSLATE = 0;
END IF;
IF NEW.DETAIL_RETURNDATE IS NOT NULL THEN
IF NEW.DETAIL_RETURNDATE - OLD.DETAIL_DUEDATE > DATE_FORMAT(NEW.DETAIL_RETURNDATE, 'HH24:MI:SS') <= '12:00:00' THEN
SET NEW.DETAIL_DAYSLATE = DATEDIFF(OLD.DETAIL_DUEDATE, NEW.DETAIL_RETURNDATE)*-1;
ELSE
SET NEW.DETAIL_DAYSLATE = 0;
END IF;
END IF;
END;//
delimiter ;
In my problem which I am trying to solve, there is a performance values table:
Staff PerformanceID Date Percentage
--------------------------------------------------
StaffName1 1 2/15/2016 95
StaffName1 2 2/15/2016 95
StaffName1 1 2/22/2016 100
...
StaffName2 1 2/15/2016 100
StaffName2 2 2/15/2016 100
StaffName2 1 2/22/2016 100
And the SQL statement as follows:
SELECT TOP (10)
tbl_Staff.StaffName,
ROUND(AVG(tbl_StaffPerformancesValues.Percentage), 0) AS AverageRating
FROM
tbl_Staff
INNER JOIN
tbl_AcademicTermsStaff ON tbl_Staff.StaffID = tbl_AcademicTermsStaff.StaffID
INNER JOIN
tbl_StaffPerformancesValues ON tbl_AcademicTermsStaff.StaffID = tbl_StaffPerformancesValues.StaffID
WHERE
(tbl_StaffPerformancesValues.Date >= #DateFrom)
AND (tbl_AcademicTermsStaff.SchoolCode = #SchoolCode)
AND (tbl_AcademicTermsStaff.AcademicTermID = #AcademicTermID)
GROUP BY
tbl_Staff.StaffName
ORDER BY
AverageRating DESC, tbl_Staff.StaffName
What I am trying to do is, from a given date, for instance 02-22-2016,
I want to calculate average performance for each staff member.
The code above gives me average without considering the date filter.
Thank you.
Apart from your join conditions and table names which looks quite complex, One simple question, If you want the results for a particular date then why is the need of having
WHERE tbl_StaffPerformancesValues.Date >= #DateFrom
As you said your query is displaying average results but not for a date instance. Change the above line to WHERE tbl_StaffPerformancesValues.Date = #DateFrom.
Correct me if I am wrong.
Thanks for the replies, the code above, as you all say and as it is also expected is correct.
I intended to have a date filter to see the results from the given date until now.
The code
WHERE tbl_StaffPerformancesValues.Date >= #DateFrom
is correct.
The mistake i found from my coding is, in another block i had the following:
Protected Sub TextBoxDateFrom_Text(sender As Object, e As System.EventArgs) Handles TextBoxDate.PreRender, TextBoxDate.TextChanged
Try
Dim strDate As String = Date.Parse(DatesOfWeekISO8601(2016, WeekOfYearISO8601(Date.Today))).AddDays(-7).ToString("dd/MM/yyyy")
If Not IsPostBack Then
TextBoxDate.Text = strDate
End If
SqlDataSourcePerformances.SelectParameters("DateFrom").DefaultValue = Date.Parse(TextBoxDate.Text, CultureInfo.CreateSpecificCulture("id-ID")).AddDays(-7)
GridViewPerformances.DataBind()
Catch ex As Exception
End Try
End Sub
I, unintentionally, applied .AddDays(-7) twice.
I just noticed it and removed the second .AddDays(-7) from my code.
SqlDataSourcePerformances.SelectParameters("DateFrom").DefaultValue = Date.Parse(TextBoxDate.Text, CultureInfo.CreateSpecificCulture("id-ID"))
Because of that mistake, the SQL code was getting the performance values 14 days before until now. So the average was wrong.
Thanks again.
I am trying to run this query but the query keeps giving up on me:
Update StockInvoiceInfo set Quantity = Quantity - 2 where p_id = 5 AND ProductDate = convert(Cast('31-5-2015' as datetime)) ;
After Running this code it returns an error below:
Incorrect syntax near '31-5-2015'
The datatype of the ProductDate column isDate. I am using Sql Server 2012.
You have used Convert functions but didn't supplied it with parameters. Also there is no need for this function here. Also take care of date format. I have changed it to standard format:
Update StockInvoiceInfo set Quantity = Quantity - 2
where p_id = 5 AND ProductDate = Cast('2015-05-31' as datetime)
If all you are trying to do is compare a Sql Date, then just use an agnostic format like '20150531' or easier to read '2015-05-31'. No need for casts or convert at all, i.e.
WHERE ... AND ProductDate = '2015-05-31'
However, if ProductDate isn't a date, but one of the *DATETIME* data types, and you are looking to update any time on the same day, then I believe you are looking for something like:
Update StockInvoiceInfo
set Quantity = Quantity - 2
where
p_id = 5
AND CAST(ProductDate AS DATE) = '2015-05-31';
However, the performance will be lousy as the clause isn't likely to be SARGable. You're better off simply doing:
AND ProductDate >= '2015-05-31' AND ProductDate < '2015-06-01';
(Resist the temptation to use between, or hacks like ':23:59:59' as there will be data corner cases which will bite you)
use CAST('5-31-2015' as DATETIME)
with the above update statement you started convert but with incomplete syntax
here the convert syntax
Update StockInvoiceInfo
set Quantity = Quantity - 2
where p_id = 5
AND ProductDate = convert(datetime,Cast('31-5-2015' as varchar),103) ;
I am generating a report in SSRS, in which I got a start date field, which should populate the Start date of the current quarter automatically. Can someone please help me, how do I do this?. Thanks heaps
T-SQL for current quarter:
SELECT DATEADD(qq,DATEDIFF(qq,0,GETDATE()),0) AS FirstDayOfCurrentQtr
Or SSRS expression if you want to set the value that way:
=DateAdd(DateInterval.Quarter, DateDiff(DateInterval.Quarter, CDate("1/1/1900"), Today()), CDate("1/1/1900"))
if you wanted to avoid having an additional dataset, you could use this expression as the default value for the parameter:
=DateSerial(Datetime.Today.Year,3 * ((datetime.Today.Month -1 )/3 + 1) -2, 1)
That's pretty ugly though. More ideally create a function that you cacan call that from the expression:
Function getQuarter (byVal d As DateTime) As DateTime
Dim quarter as Integer = (d.Month -1) / 3 + 1
Dim quarterStart AS new DateTime(d.Year, 3 * quarter - 2, 1)
getQuarter = quarterStart
End Function
Put the above in the code section of the report properties and in the expression call it by:
=Code.GetQuarter(Today)