I have 6 fields in my "table1".
Current Date
Next Adjustment Date
Months Elapsed
Index 0
Index 1
Index 2.
I'm trying to create an update query for Index 1 where if the (Current Date+Months Elapsed) < Next Adjustment Date then Index 1 is Index 0 if not I want Index 1 to stay at whatever value it currently has.
I tried this
iif(DateAdd("m",[Table1]![Months Elapsed],[Table1]![Current Date])<[Table1]![Next Adjustment Date], [Table1]![Index 0]
As soon as I put in the [Table1]![Next Adjustment Date] in the iif formula I receive "The expression you entered contains invalid syntax" error.
iif( is not matched by a closing )
Work out the syntax in a SELECT query. Then use that working field expression in your UPDATE. Here is my suggestion ...
SELECT
IIf
(
DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date],
t1.[Index 0]
)
FROM Table1 AS t1;
Note your IIf lacked the third argument, which is the value to return when the condition (the first argument) is not True. The database engine will not complain and will return Null in that situation. See also this answer.
However your description suggests you may actually want this ...
IIf
(
DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date],
t1.[Index 0],
t1.[Index 1]
)
... but for an UPDATE, it makes more sense to me to move that condition to the WHERE clause and update only those rows ...
UPDATE Table1 AS t1
SET t1.[Index 1] = t1.[Index 0]
WHERE DateAdd('m', t1.[Months Elapsed], t1.[Current Date]) < t1.[Next Adjustment Date];
You don't have the false part of the IIf specified. Try this;
IIf(DateAdd("m",[Table1]![Months Elapsed],[Table1]![Current Date])< [Table1]![Next Adjustment Date], [Table1]![Index 0], [Table1]![Index 1])
However I'm concerned that you have apparently fields stored for Current Date and Months Elapsed. Aren't these both calculated on the fly? They should be.
Related
I am trying to create a query which will update a blank "To Date" field with the day prior to next updated date.
Example, an [Item Number] standard cost was updated ([From Date]) on 01/03/2019, then again on 01/07/2019 and then again on the 01/01/2020.
I would like an adjacent column which is updated with [To Date] of 30/06/2019, 31/12/2019.
I will run a subsequent query which updates blanks (i.e. current cost as there is no next [From Date]) to Today End of Month date (I assume I need a separate query for this rather than an IIF which can populate Blanks as part of this update query?)
Currently I have below, but it is updating the [To Date] with day prior to the newest date in all instances (i.e 31/12/2019 for first 2 rows), I understand that I need a SORT within the below query:
Many thanks in advance from this first time poster!
UPDATE
Standards
INNER JOIN
Standards AS Standards_1
ON
(Standards.[Item number] = Standards_1.[Item number]) AND (Standards.[From date] < Standards_1.[From date])
SET
Standards.[To Date 2] = Standards_1.[From date]-1;
This might work, but the performance migth be a bit slow:
UPDATE Standards
SET [To Date] = Nz(
DateAdd("d", -1,
DMin("[From Date]", "Standards", "[Item Number]=" & [Item Number] & " AND [From Date] > #" & [From Date] & "#")
)
, DateSerial(Year(Date()), Month(Date())+1, 0)
)
Start from the DMin function, which will lookup the next date greater than the current date for the item.
DateAdd function will subtract one day from this date.
Nz will use the value returned by the DateSerial function if the DateAdd function result is Null.
DateSerial function returns the end date of the current month.
# are added because of the date value of the [From Date] field in the criteria of the DMin.
Instead of using the [From Date] field in the DMin function criteria, you can consider using the Autonumber Primary Key field. You'll need to remove the # in the criteria.
Everything between Nz(...) will need to be on one line.
This solves both of your requirements, just test the performance.
I have an expression that outputs the number of rows: =CountRows("DataSet1").
I want to filter it by date range using parameters in order to output the number of rows within that range.
I have tried this: =CountRows(IFF Fields!DATE_OF_REQUEST.Value, "DataSet1" >= Parameters!startDate.Value
AND Fields!DATE_OF_REQUEST.Value, "DataSet1" <= Parameters! endDate.Value
("DataSet1"))
How can I achieve the desired output?
Probably not the most efficient solution, but, is the way I go about making date range reports:
I would apply the date range in the where clause of your dataset:
WHERE Date_of_Request between #startDate and #endDate
For this, I would create another identical dataset that just looks at distinct records and apply the where clause to get the most accurate figure.
I'm assuming the logic in your COUNTROWS expression is correct here...
What you need to do is evaluate each row and if it matches you criteria return 1 else return 0 then sum the results of this. So you can modify you expression slightly like this.
=SUM(
IIF(
Fields!DATE_OF_REQUEST.Value >= Parameters!startDate.Value
AND Fields!DATE_OF_REQUEST.Value <= Parameters!endDate.Value,
1,
0,
"DataSet1"
)
)
I'm doing this from memeory so the position of the scope "DataSet1" might be incorrect.
tblDurations
TaskID : Number
Assigned Date : Date/Time
Start Date : Date/Time
End Date : Date/Time
SELECT TaskID,
Count(TaskID) As [Task Count],
Min(Nz([Start Date], [Assigned Date])) as [Min of Start Date],
Max([End Date]) as [Max of End Date],
DateDiff("d", Min(Nz([Start Date], [Assigned Date])), Max([End Date])) + 1 as [Date Range]
FROM tblDurations
GROUP BY TaskID
Output:
TaskID Task Count Min of Start Date Max of End Date Date Range
1 3 16/08/2018 10/01/2019 1
2 2 4/09/2017 07/09/2017 4
3 3 13/09/2017 08/01/2018 118
I am getting the occasional row as shown in row 1 (TaskID = 1) which should equal 148!
After a lot of checking I determined this occurs for dates that are ambiguous. By that I mean where the day and months values can be confused for each other.
I'm in Australia where the date formnat is dd/mm/yyyy. However I believe the datediff function is confusing the day and month order and returning Zero (plus my 1 = 1).
How can I overcome this issue?
The problem was not the ambiguous dates. Looking closer I found various non ambiguous dates returning bad values.
The problem was the use of an Nz function which I was using like this :
Min(NZ([Start Date], [Assigned Date]))
Which I took to mean take the Min of either the Start Date, but if the start date does is NULL then the min of the Assigned Date.
What does work is this :
Nz(Min([StartDate], Min(Assigned Date))
All fixed.
Which begs the question. Why only sometimes? As it was not related to Start Dates being NULL or not NULL.
Thanks everyone for feed back!
I want to filter my query in a data set in a way, where I got dates from beginning of the month until yesterday. First part is easy, I'm passing month from report parameters, so I got values from every day in month, but somehow I have to limit this until yesterday. I tried putting this expression in where clause, but it didn't work at all since I don't have date on rows: FILTER([Date of shipment].[Date], [Date of shipment].[Date] < Format(Now(), "yyyyMMdd").
I know I could filter rows, but important thing is, I don't want Date to be displayed on the rows.
Edit: additionally I can use parameter supplied by main report, which is yesterday's date. But how do I limit date without putting it on rows? Something like this doesn't works: IIF( STRTOSET(#ShipmentDate, CONSTRAINED).Count = 1, STRTOSET(#ShipmentDate, CONSTRAINED), [Shipment Date].[Date] < #ShipmentDate))
You already have something similar to this:
SELECT
{} ON 0
,
[Date].[Calendar].[Date].&[20050101]
:
StrToMember
('[Date].[Calendar].[Date].&[20050105]' //<<hard-coded to illustrate
,constrained
) ON 1
FROM [Adventure Works];
Returns:
Most cubes have a multi-level date hierarchy - so you could change your code to something like the so that next year you do not need to change the hard-coded bit:
SELECT
{} ON 0
,
Descendants
(
Exists
(
[Date].[Calendar].[Calendar Year].MEMBERS
,StrToMember
(#ShipmentDate
,constrained
)
).Item(0)
,[Date].[Calendar].[Date]
).Item(0)
:
StrToMember
(#ShipmentDate
,constrained
) ON 1
FROM [Adventure Works];
If #ShipmentDate is set to '[Date].[Calendar].[Date].&[20060105]' then I get the following:
Solution:
Since I had Month passed through parameter dates were limited to current month. This allowed me to do this:
[Shipment date].[Datw].&[20160101] : STRTOMEMBER(#ShipmentDate, constrained)
Way I did this is ugly, but it works(it may need mainteance, to change date to 20170101 in next year and so on).
I have searched SO for this question and found slightly similar posts but was unable to adapt to my needs.
I have a database with server requests since forever, each one with a timestamp and i'm trying to come up with a query that allows me to create a heatmatrix chart (CCC HeatGrid).
The sql query result must represent the server load grouped by each hour of each weekday.
Like this: Example table
I just need the SQL query, i know how to create the chart.
Thank you,
Those looks like "counts" of rows.
One of the issues is "sparse" data, we can address that later.
To get the day of the week ('Sunday','Monday',etc.) returned, you can use the DATE_FORMAT function. To get those ordered, we need to include an integer value 0 through 6, or 1 through 7. We can use an ORDER BY clause on that expression to get the rows returned in the order we want.
To get the "hour" across the top, we can use expressions in the SELECT list that conditionally increments the count.
Assuming your timestamp column is named ts, and assuming you want to pull all rows from the year 2014, we start with something like this:
SELECT DAYOFWEEK(t.ts)
, DATE_FORMAT(t.ts,'%W')
FROM mytable t
WHERE t.ts >= '2014-01-01'
AND t.ts < '2015-01-01'
GROUP BY DAYOFWEEK(t.ts)
ORDER BY DAYOFWEEK(t.ts)
(I need to check the MySQL documentation, WEEKDAY and DAYOFWEEK are real similar, but we want the one that returns lowest value for Sunday, and highest value for Saturday... i think we want DAYOFWEEK, easy enough to fix later)
The "trick" now is the columns across the top.
We can extract the "hour" from timestamp using the DATE_FORMAT() function, the HOUR() function, or an EXTRACT() function... take your pick.
The expressions we want are going to return a 1 if the timestamp is in the specified hour, and a zero otherwise. Then, we can use a SUM() aggregate to count up the 1. A boolean expression returns a value of 1 for TRUE and 0 for FALSE.
, SUM( HOUR(t.ts)=0 ) AS `h0`
, SUM( HOUR(t.ts)=1 ) AS `h1`
, SUM( HOUR(t.ts)=2 ) AS `h2`
, '...'
, SUM( HOUR(t.ts)=22 ) AS `h22`
, SUM( HOUR(t.ts)=23 ) AS `h23`
A boolean expression can also evaluate to NULL, but since we have a predicate (i.e. condition in the WHERE clause) that ensures us that ts can't be NULL, that won't be an issue.
The other issue we can encounter (as I mentioned earlier) is "sparse" data. To illustrate that, consider what happens (with our query) if there are no rows that have a ts value for a Monday. What happens is that we don't get a row in the resultset for Monday. If it does happen that a row is "missing" for Monday (or any day of the week), we do know that all of the hourly counts across the "missing" Monday row would all be zero.