I have some records like this:
Datetime | Type |
2012-02-23 22:00:11 1
2012-02-23 22:02:14 2
2012-02-23 22:03:56 1
2012-02-23 22:04:11 1
2012-02-23 22:33:21 2
....
I will generate a list which shows:
The Datetime field
and, if Type = 2, the time difference between Last type 1 and actual Type2 Record.
Formatted with HH:MM:SS
Example for the above mentionend Data:
Datetime | Type | Diff
2012-02-23 22:00:11 1
2012-02-23 22:02:14 2 00:02:03 (Diff to 22:00:11)
2012-02-23 22:03:56 1
2012-02-23 22:04:11 1
2012-02-23 22:33:21 2 00:29:25 (Diff to 22:03:56)
I tried to use Variables in a different way.
But, as so often recently, unsuccesfull :-)
(i´m usinfg iReport 4.5.0)
Any ideas ?
thx Christian
First, create a variable $V{Diff} that calculates the difference between $F{Datetime} for all rows. This gives you the values you want (and a bunch that you don't need).
Second, only display $V{Diff} when $F{Type} equals 2.
But it's the details that make it fun. That variable is not entirely obvious in JasperReports. You actually need two variables, and they have to be defined in the correct order.
$V{Diff} Expression: $F{adate}.getTime() - $V{LastType1Date}
$V{LastType1Date} Expresion: ($F{type}.intValue() == 1) ? $F{adate}.getTime() : $V{LastType1Date}
Then the print when expression is easy: $F{type}.intValue() == 2 And you get what you need:
I have ignored the interval formatting, but I think this solves the key issues for you. You just need to transform the milliseconds into the format you want.
Try putting this in your variable expression (located in the variable's properties)
$F{Datetime}.equals($F{type}.equals(2))-$F{Datetime}.equals($F{type}.equals(1))
Create a Date variable called lastType1DateTime and for the variable expression put:
($F{Type} == 1) ? $F{DateTime} : $V{lastType1DateTime}
This variable will always hold the last type 1 date. Then simply do your diff in the detail field for type 2 rows.
Related
I have a list of date ranges for the past 8 quarters given by the below function
q) findLastYQuarters:{reverse("d"$(-3*til y)+m),'-1+"d"$(-3*-1+til y)+m:3 bar"m"$x}[currentDate;8]
q) findLastYQuarters
2020.01.01 2020.03.31
2020.04.01 2020.06.30
2020.07.01 2020.09.30
2020.10.01 2020.12.31
2021.01.01 2021.03.31
2021.04.01 2021.06.30
2021.07.01 2021.09.30
2021.10.01 2021.12.31
I need to produce a separate list that labels each item in this list by a specific format; the second list would need to be
1Q20,2Q20,3Q20,4Q20,1Q21,2Q21,3Q21,4Q21
This code needs to be able to run on it's own, so how can I take the first list as an input and produce the second list? I thought about casting the latter date in the range as a month and dividing it by 3 to get the quarter and extracting the year, but I couldn't figure out how to actually implement that. Any advice would be much appreciated!
I'm sure there are many ways to solve this, a function like f defined below would do the trick:
q)f:{`$string[1+mod[`month$d;12]%3],'"Q",/:string[`year$d:x[;0]][;2 3]}
q)lyq
2020.01.01 2020.03.31
2020.04.01 2020.06.30
2020.07.01 2020.09.30
2020.10.01 2020.12.31
2021.01.01 2021.03.31
2021.04.01 2021.06.30
2021.07.01 2021.09.30
2021.10.01 2021.12.31
q)f lyq
`1Q20`2Q20`3Q20`4Q20`1Q21`2Q21`3Q21`4Q21
Figured it out.
crop:findLastYQuarters;
crop[0]:crop[0][1];
crop[1]:crop[1][1];
crop[2]:crop[2][1];
crop[3]:crop[3][1];
crop[4]:crop[4][1];
crop[5]:crop[5][1];
crop[6]:crop[6][1];
crop[7]:crop[7][1];
labels:()
labelingFunc:{[r] temp:("." vs string["m"$r]); labels,((string(("J"$temp[1])%3)),"Q",(temp[0][2,3])};
leblingFunc each crop;
labels
How would you parse a date string in format "dd/MM/yyyy" using q kdb?
It is possible when the month argument is first "MM/dd/yyyy" as follows:
"D"$"1/20/2014"
2014-01-20d
However if day is first "dd/MM/yyyy"
"D"$"20/1/2014"
0Nd
KDB supports parsing of different datetime formats. Check details here:
https://code.kx.com/q/ref/casting/#tok
For your case you need to set 'z' option which specifies the format for date parsing.
0 is "mm/dd/yyyy" and 1 is "dd/mm/yyyy".
Details: https://code.kx.com/q/ref/syscmds/#z-date-parsing
This is how you do it for your example:
q) \z 1
q) "D"$"20/1/2014"
q) 2014.01.20
If you want to avoid changing system variables and have greater control over all possible date formats you can always write a custom date parser such as this:
f:{"D"$raze"0"^neg[4 2 2]$(y vs z)iasc`YYYY`MM`DD?x}
Which takes 3 parameters; date format expected, delimiter and date string. To handle your example it would be set up as follows:
q)f[`MM`DD`YYYY;"/";"1/20/2014"]
2014.01.20
It can also handle more unconventional date formats:
q)f[`MM`YYYY`DD;"p";"1p2014p20"]
2014.01.20
Obviously the above is overkill compared to inbuilt date parsing for your example but it does give a greater degree of flexibility.
Note that you do not have to pad with zeroes (tested with 3.3):
q)"." sv ("/" vs "1/20/2014") 2 0 1
"2014.1.20"
q)"D"$ "." sv ("/" vs "1/20/2014") 2 0 1
2014.01.20
In a function:
q)f:{"D"$"."sv("/"vs x)2 0 1}
q)f "1/20/2014"
2014.01.20
If you want a function that can handle both lists and individual dates:
q)g:{"D"$$[10=type x;"."sv("/"vs x)2 0 1;"."sv/:("/"vs/:x)[;2 0 1]]}
q)g "7/20/2014"
2014.07.20
q)g ("1/20/2014";"7/20/2014";"03/20/2014")
2014.01.20 2014.07.20 2014.03.20
... which is a little better than using each:
q)\ts:100000 g ("1/20/2014";"7/20/2014";"03/20/2014")
308 1168
q)\ts:100000 f each ("1/20/2014";"7/20/2014";"03/20/2014")
327 1312
... and quicker than padding/razing:
q)h:{"D"$raze"0"^neg[4 2 2]$(y vs z)iasc`YYYY`MM`DD?x}[`MM`DD`YYYY;"/";]
q)\ts:100000 h each ("1/20/2014";"7/20/2014";"03/20/2014")
615 1312
I have a report like the image below:
Note that the sections separated by a blank space are grouped by the month and are iterated over a group band. I want to put partial in the summary band by the type of the register, like in the example figure get the sum for Register type A in January = 10, February = 5, March = 1 so as the total = 10 + 5 + 1 = 16. So the summary will look like:
How can I achieve that kind of conditional sum in jasper? Thanks in advance.
After trying a little bit with iReport I found a solution: to get the partial sum by type you have to add a variable that has the calculation type as "sum" and the reset type set as "Report". Once you set the values you have to create a variable Expression that has value only when the cell value of type is the desired value, so for the example in the question, in the column Value of the summary band in cell with the value "16" you have the expression :
$F{type}.equals("A") ? $F{value} : 0
and so on for the other types in the summary.
Hi I am a newbie and have a problem I have been trying to solve for weeks. I have a table imported from excel with dates in text format (because dates go back to 1700s) Most are in the format "mmmyyyy", so it is relatively easy to add "1" to the date, convert to date format, and sort in correct date order. The problem I have is that some of the dates in the table are simply "yyyy", and some are empty. I cannot find an expression that works to convert these last two to eg 1 Jan yyyy and 1 Jan 1000 within the same expression. Is this possible, or would I need to do this in two queries? Sorry if this question is very basic - I cannot find an answer anywhere.
TIA
You can do something like:
Public Function ConvertDate(Byval Expression As Variant) As Date
Dim Result As Date
If IsNull(Expression) Then
Result = DateSerial(1000, 1, 1)
ElseIf Len(Expression) = 4 Then
Result = DateSerial(Expression, 1, 1)
Else
Result = DateValue(Right(Expression, 4) & "/" & Left(Expression, 3) & "/1")
End If
ConvertDate = Result
End Function
I have a table 'X' like this:
name value score
joy 3 60
rony 8 50
macheis 20 20
joung 2 80
joy 8 3
joy 90 0
joung 4 78
machies 3 23
joy 7 99
I want to select 2 random rows(with name, value, score) where the name is 'joy'.
I applied something like this:
mnew = datasample(find(X.name=='joy'),2); but it does not work! and gives me the error: Undefined operator '==' for input arguments of type 'cell'.
The rows should be selected randomly (with all columns values) where the name is joy.
Does anyone any other solution of this problem? how can i do it in MATLAB?
You have the right idea, but in order to check for the presence of a string within a cell array of strings, you need to use strcmp, ismember, or another method for comparing a string to a cell array.
You probably also want to specify that you don't want to use replacement when calling datasample so you don't get the same row twice.
subx = X(datasample(find(strcmp(X.name, 'joy')), 2, 'Replace', false),:);