I'm using InfoPath 2003 to produce a form which includes a repeating table of records that include a date field (StartDate) and a value field (TotalElapsed). I have date pickers for start and end dates on the form (beginDate and endDate), and there is a text box after the table which I want to have show the total sum of the integer field for records that have a date between the start and end date selections. The text box value parameter generated when I use the 'Insert Field or Group...' and 'Filter Data...' options, is below:
sum(#TotalElapsed[msxsl:string-compare(#StartDate, beginDate) >= 0 and msxsl:string-compare(#StartDate, endDate) <= 0])
This gives almost the correct sum calculation, with the exception that any records with a date that matches the end date are not included in the sum. Any records with dates from (and including) the start date, up to the day before the end date, are all included in the sum. Any ideas why the end date records aren't included in the sum?
Thanks
The above equation works fine. To use the >= and <= the Start Date should be in type of Date.
sum(Total[msxsl:string-compare(StartDate, BeginDate) >= 0 and msxsl:string-compare(StartDate, EndDate) <= 0])
Related
How to convert date to financial quarters:
3/31/2018 to 2018q1
I pulled a dataset from the FDIC website. Their date format is currently dd/mm/yyyy.
I am interested in creating a Scatter Plot/Bubble Chart using Gapminder.
However Gapminder needs each date to be converted to financial quarters. e.g. yyyyq1, yyyyq2, yyyyq3, or yyyyq4. e.g. 20017q1, 20017q2, 20017q3, or 2017q4.
This query needs to convert the date to financial quarters, but doesn't already do so. What needs to be added to convert "repdte" output dd/mm/yyyy to yyyyq1?
SELECT
PCR.name,
PCR.repdte as Quarter,
PCR.idlncorr as NetLoansAndLeasesToCoreDeposits,
CAST(LD.IDdeplam as int) as DepositAccounts$GreaterThan$250k
from All_Reports_20180630_Performance_and_Condition_Ratios as PCR
join
'All_Reports_20180630_Deposits_Based_on_the_$250,000_Reporting_Threshold'
as LD on PCR.cert = LD.cert
UNION ALL
SELECT
PCR.name,
PCR.repdte as Quarter,
PCR.idlncorr as NetLoansAndLeasesToCoreDeposits,
CAST(LD.IDdeplam as int) as DepositAccounts$GreaterThan$250k
FROM All_Reports_20180331_Performance_and_Condition_Ratios as PCR
JOIN
'All_Reports_20180331_Deposits_Based_on_the_$250,000_Reporting_Threshold'
as LD on PCR.cert = LD.cert
What I currently have
Quarter
03/31/2018
The format that Gapminder needs to render the Bubble Chart:
ReportDate
2009q1
I believe that using
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER)
will convert the date for you.
For example, consider the following :-
DROP TABLE IF EXISTS PCR;
CREATE TABLE IF NOT EXISTS PCR (repdte);
INSERT INTO PCR VALUES('01/31/2009'),('02/31/2009'),('03/31/2009'),('04/31/2009'),('05/31/2009'),('06/31/2009'),('07/31/2009'),('08/31/2009'),('09/31/2009'),('10/31/2009'),('11/31/2009'),('12/31/2009');
SELECT PCR.repdte,
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER) FROM PCR;
Which results in :-
Additional
Re comment :-
It works. However, I'm getting an output of '018q2' instead of
'2018q2'. What would I change to add a '2' to '018q2'?
This would appear to be due to the date have a variable length day part, that is if the day part is less then 10 then it is a single numeric rather than being padded with 0 and two numerics when 10 or more.
The following could be used :-
replace(substr(PCR.repdte,6),'/','')||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER)
this works by taking the year from from the 6th character and removing the / if it exists, consider the following
:-
DROP TABLE IF EXISTS PCR;
CREATE TABLE IF NOT EXISTS PCR (repdte);
INSERT INTO PCR VALUES('01/31/2009'),('02/1/2009'),('03/31/2009'),('04/31/2009'),('05/1/2009'),('06/31/2009'),('07/31/2009'),('08/1/2009'),('09/31/2009'),('10/31/2009'),('11/31/2009'),('12/31/2009');
SELECT PCR.repdte,
substr(PCR.repdte,7,4)||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER), -- OLD
replace(substr(PCR.repdte,6),'/','')||'q'||CAST(1+((substr(PCR.repdte,1,2)-1) / 3) AS INTEGER) -- MODIFIED
FROM PCR;
Which results in :-
I have a COGNOS package for data on processes within my company. They all have a start date, and unfinished processes have no end date. A process is active on date x if the start date is before x, and the end date is after x, or is empty. The package doesn't have a time series.
The company needs a report with the number of active processes at the end of each month, for the past two years. With no time series to iterate, I had to be creative. I created 24 data items, each with the formula below:
IF (([Start Date] <= _last_of_month(_add_months(current_date;-1))) and
(([End Date] is missing) or
([End Date] > _last_of_month(_add_months(current_date;-1)))))
THEN (1) ELSE (0)
... subtracting 1 to 24 months. Then, I added each on a column on the report's crosstable.
Well, this solution is really ugly, and unmaintanable. Is there a way to iterate a variable on Report Studio, creating a line or column for each iteration?
Thanks!
You can simulate time series in Report Studio.
There are some options:
If you are allowed to SQL in RS. Create a Query Subject like:
select _last_of_month(_add_months(current_date;-1)) as Month
union all
select _last_of_month(_add_months(current_date;-2)) as Month
union all
....
Create a query subject from existing table with dates. Query item [Month]
_last_of_month([date_field])
Filter it by
[date_field] < _add_months(current_date;-24)
and check query property "Auto Group and Summarize" is set "Yes".
Be careful an choose small but dense table as a source.
Create Query subject based on any existing table with more than 24 rows. Add a Query Item with expression
1
Call it "1" as well. Add another QI, call it [Back], expression
running-total([1])
Filter it:
[Back] <= 24
Add another QI with expression
_last_of_month(_add_months(current_date;-[Back]))
This is your [Month] field
Than join this Query Subject with your process list by condition
[Time series].[Month] > [Process].[Start Date] and
([Time series].[Month] < [Process].[End Date] or [End Date] is missing)
Than just count rows for every [Month]
In one of my tables I have datetime field in which the data in the table column is populated with something like "2016-01-07 01:33:00".
What I want to do is change ONLY the date to a random date within a range (ie: 2016-02-01 thru 2016-02-28) without changing the time. The end result might be "2016-02-13 01:33:00".
What mysql command string would accomplish this task?
Something like
UPDATE someTable SET someDate = DATE_ADD(
someDate,
INTERVAL
DATEDIFF(rangeStart, someDate) +
ROUND(RAND()*DATEDIFF(rangeEnd, rangeStart))
DAY
);
where someTable.someDate is your existing data, and rangeStart and rangeEnd are the boundaries of your target date range.
Here you take the initial date, add enough days to it to reach the range start, and then further add a random number of days no greater than the number of days in your target range.
In MsSQL it could be:
select dateadd(day,cast((RAND() * 30) as int),getdate())
Substitute getdate() with your input date.
(RAND() * 30) is used to randomly generate a number of days up to 30.
I need to retrieve the rows that service_date is greater than prod_date.
The data type for prod_date is VARCHAR(10) (2/20/2014 for example) and the data type for service_date is DATE (YYYYMMDD). If I query service_date using "select service_date from service where service_date ='20140201'", the result is showing "2/1/2014" in the result grid. However, it does not work in the query below when I convert service_date to varchar to compare with prod_date. It pulls out all the rows instead of the ones that have greater service_date.
SELECT P.PROD_ID, P.PROD_DESC, S.PROD_ID, S.SERVICE_LOC
FROM PRODUCT P
INNER JOIN SERVICE S
WHERE P.PROD_ID = S.PROD_ID
AND CAST(S.SERVICE_DATE AS VARCHAR(10)) >= P.PROD_DATE
I suggest you use date ordering instead of string/varchar ordering if possible for simplicity and since its [ probably ] closer to what your interested in and less likely to confuse
For example
'01/02/2014' >= '04/01/2013' -- if these are dates or cast to dates
but
'01/02/2014' < '04/01/2013' -- if these are strings
So to keep things simple, it makes sense to cast PROD_DATE to a date when comparing these two fields like :
SELECT P.PROD_ID, P.PROD_DESC, S.PROD_ID, S.SERVICE_LOC
FROM PRODUCT P
INNER JOIN SERVICE S
WHERE P.PROD_ID = S.PROD_ID
AND S.SERVICE_DATE >= cast(P.PROD_DATE as date format 'DD/MM/YYYY')
;
if theres any doubts on prod_dates quality as valid dates can check the conversion on all dates first ( before running/adjusting above )
This isn't 100% error proof given your date is character and could have unexpected values. It does show how you can append a leading 0 to the month value and cast it to a date when the month is determined to be a single digit based on the location of the / in the second position of the PROD_DATE value for a given row.
SELECT CASE WHEN POSITION('/' IN TRIM(P.PROD_DATE)) = 2
THEN CAST('0'|| TRIM(P.PROD_DATE) AS CHAR(10)) AS DATE FORMAT 'MM/DD/YYYY')
ELSE CAST(P.PROD_DATE AS DATE FORMAT 'MM/DD/YYYY')
END AS PROD_DATE_
FROM PRODUCT P;
I am new to SSRS.
I have a dataset, my dataset brings data from a stored procedure.
one of the parameters of my sp is StartDate and another one is EndDate. Their type is datetime
And the table has a dateTime Column called Date.
I have two gauges and I wanna bind integer values to my gauges.
First one is the count of rows where Date < DateAdd(DateInterval.Hour,24,StartDate)
and te second is count of rows where Date > DateAdd(DateInterval.Hour,24,StartDate)
How will I write the exact script. Whatever I wrote is not working.
I appreciate any help, thanks.
You need to set the gauge Pointer value as something like:
=Sum(IIf(DateDiff(DateInterval.Day, Parameters!StartDate.Value, Fields!Date.Value) >= 1
, 1
, 0))
This is counting rows where the time difference is less than a day compared to the parameter StartDate. Just change it slightly to get those where the difference is at least a day:
=Sum(IIf(DateDiff(DateInterval.Day, Parameters!StartDate.Value, Fields!Date.Value) >= 1
, 0
, 1))
Worked fine for me in a quick test: