Hi,
I am new to q. I am trying to find continuous time range for table below? Maybe it’s easy but I can’t figure it out on Friday afternoon…
q)show test:( c1:a
aa
bb
aa
ab
b`a; c2: 2016.01.01+til 11)
c1 c2
-------------
a 2016.01.01
a 2016.01.02
a 2016.01.03
b 2016.01.04
b 2016.01.05
a 2016.01.06
a 2016.01.07
a 2016.01.08
b 2016.01.09
b 2016.01.10
a 2016.01.11
how do I query it so that I can get:
c1 StartDate EndDate
a 2016.01.01 2016.01.03
b 2016.01.04 2016.01.05
a 2016.01.06 2016.01.08
b 2016.01.09 2016.01.10
a 2016.01.11 2016.01.11
Many thanks!
Shaw
Use differ, and reverse to get the endings:
q)test:( c1:a
aa
bb
aa
ab
b`a; c2: 2016.01.01+til 11)
q)select c1, start:c2, end:(exec reverse c2 from reverse test where differ c1) from test where differ c1
c1 start end
a 2016.01.01 2016.01.03
b 2016.01.04 2016.01.05
a 2016.01.06 2016.01.08
b 2016.01.09 2016.01.10
a 2016.01.11 2016.01.11
Couple of ways to do this:
- Using groupby
q) value select first c1,startDate:first c2, endDate:last c2 by sums differ c1 from test
- Take the row indexes where symbol value changes and filter out values from columns using those indexes.
q) r: where differ test`c1
q) select c1 r, startDate:c2 r, endDate: c2 1_(r,count test)-1 from test
Second solution performs better than the first.
I see, very helpful. Thank you all!
I added extra conditions to make sure c2 is consecutive in days…
works if there is gap between days.
test:( c1:a
aa
bb
aa
ab
ba
a; c2:(2016.01.01+til 11), 2016.02.01)
r: asc distinct ((where differ (1i, 1_deltas testc2)), (where differ test
c1))
select c1 r, startDate:c2 r, endDate: c2 1_(r,count test)-1 from test
r startDate endDate
a 2016.01.01 2016.01.03
b 2016.01.04 2016.01.05
a 2016.01.06 2016.01.08
b 2016.01.09 2016.01.10
a 2016.01.11 2016.01.11
a 2016.02.01 2016.02.01
Have a great weekend!
An alternative that might be more intuitive:
q)test:([] c1:
aa
ab
ba
aa
bb
aa; c2:(2016.01.01+til 11), 2016.02.01)q)select first c1,start:first c2,end:last c2 by sums 1<>(deltas@;c2)fby c1 from testc1| c1 start end--| ------------------------1 | a 2016.01.01 2016.01.032 | b 2016.01.04 2016.01.053 | a 2016.01.06 2016.01.084 | b 2016.01.09 2016.01.105 | a 2016.01.11 2016.01.116 | a 2016.02.01 2016.02.01