Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
holmlund
Contributor III
Contributor III

Challenging: Conditionally split string

I need to split this string on each $A where interval between following $A-date is more than 60 days?

How would I achieve this?

RecordId, String

RecordIdOriginalString
1000A01.07.2015 00:00:00|$S07.07.2015 00:00:00|$B07.07.2015 00:00:00|$A10.07.2015$CK16.07.2015 00:00:00|$O16.07.2015 00:00:00|$A12.10.2015 00:00:00|$S12.10.2015 00:00:00|$CI16.10.2015 00:00:00|$A19.07.2016 00:00:00|$S20.07.2016 00:00:00|$B04.08.2016 00:00:00|$CI23.08.2016 00:00:00

Wanted output:

RecordIdSplitString
1000_1A01.07.2015 00:00:00|$S07.07.2015 00:00:00|$B07.07.2015 00:00:00|$A10.07.2015$CK16.07.2015 00:00:00|$O16.07.2015 00:00:00
1000_2$A12.10.2015 00:00:00|$S12.10.2015 00:00:00|$CI16.10.2015 00:00:00
1000_3$A19.07.2016 00:00:00|$S20.07.2016 00:00:00|$B04.08.2016 00:00:00|$CI23.08.2016 00:00:00

Can't use subfield as it would split into 4 rows, not taking my condition into consideration.

1 Solution

Accepted Solutions
sunny_talwar

Try this....

Table:

LOAD RowNo() as Sort,

  RecordId,

  OriginalString,

  '$A' & NewString as NewString,

  Date(Floor(Date#(SubField(NewString, '|', 1), 'DD.MM.YYYY hh:mm:ss'))) as Date

Where Len(Trim(NewString)) > 0;

LOAD RecordId,

  OriginalString,

  SubField('|' & OriginalString, '|$A') as NewString;

LOAD * INLINE [

    RecordId, OriginalString

    1000, $A01.07.2015 00:00:00|$S07.07.2015 00:00:00|$B07.07.2015 00:00:00|$A10.07.2015 00:00:00|$CK16.07.2015 00:00:00|$O16.07.2015 00:00:00|$A12.10.2015 00:00:00|$S12.10.2015 00:00:00|$CI16.10.2015 00:00:00|$A19.07.2016 00:00:00|$S20.07.2016 00:00:00|$B04.08.2016 00:00:00|$CI23.08.2016 00:00:00

];

TempTable:

LOAD *,

  If(Date <= Previous(Date) + 60, Alt(Peek('Flag'), 1), RangeSum(Peek('Flag'), 1)) as Flag

Resident Table;

FinalTable:

LOAD RecordId & '_' & Flag as RecordId,

  Concat(DISTINCT NewString, '|') as SplitString

Resident TempTable

Group By RecordId, Flag;

DROP Table Table, TempTable;

View solution in original post

7 Replies
sunny_talwar

Try this:

Table:

LOAD RowNo() as Sort,

  *,

  Date(Floor(Date#(KeepChar(NewString, '0123456789.: '), 'DD.MM.YYYY hh:mm:ss'))) as Date;

LOAD RecordId,

  OriginalString,

  SubField(OriginalString, '|') as NewString;

LOAD * INLINE [

    RecordId, OriginalString

    1000, A01.07.2015 00:00:00|$S07.07.2015 00:00:00|$B07.07.2015 00:00:00|$A10.07.2015 00:00:00|$CK16.07.2015 00:00:00|$O16.07.2015 00:00:00|$A12.10.2015 00:00:00|$S12.10.2015 00:00:00|$CI16.10.2015 00:00:00|$A19.07.2016 00:00:00|$S20.07.2016 00:00:00|$B04.08.2016 00:00:00|$CI23.08.2016 00:00:00

];

TempTable:

LOAD *,

  If(Date <= Previous(Date) + 60, Alt(Peek('Flag'), 1), RangeSum(Peek('Flag'), 1)) as Flag

Resident Table;

FinalTable:

LOAD RecordId & '_' & Flag as RecordId,

  Concat(DISTINCT NewString, '|') as SplitString

Resident TempTable

Group By RecordId, Flag;

DROP Table Table, TempTable;

Capture.PNG

holmlund
Contributor III
Contributor III
Author

Unfortunately not 100% correct Sunny. This only test for 60 days between one of the process steps. Not only the $A's.

sunny_talwar

So the comparison needs to be only for $A?

holmlund
Contributor III
Contributor III
Author

Yes, comparisons only for the $A's.

sunny_talwar

Try this....

Table:

LOAD RowNo() as Sort,

  RecordId,

  OriginalString,

  '$A' & NewString as NewString,

  Date(Floor(Date#(SubField(NewString, '|', 1), 'DD.MM.YYYY hh:mm:ss'))) as Date

Where Len(Trim(NewString)) > 0;

LOAD RecordId,

  OriginalString,

  SubField('|' & OriginalString, '|$A') as NewString;

LOAD * INLINE [

    RecordId, OriginalString

    1000, $A01.07.2015 00:00:00|$S07.07.2015 00:00:00|$B07.07.2015 00:00:00|$A10.07.2015 00:00:00|$CK16.07.2015 00:00:00|$O16.07.2015 00:00:00|$A12.10.2015 00:00:00|$S12.10.2015 00:00:00|$CI16.10.2015 00:00:00|$A19.07.2016 00:00:00|$S20.07.2016 00:00:00|$B04.08.2016 00:00:00|$CI23.08.2016 00:00:00

];

TempTable:

LOAD *,

  If(Date <= Previous(Date) + 60, Alt(Peek('Flag'), 1), RangeSum(Peek('Flag'), 1)) as Flag

Resident Table;

FinalTable:

LOAD RecordId & '_' & Flag as RecordId,

  Concat(DISTINCT NewString, '|') as SplitString

Resident TempTable

Group By RecordId, Flag;

DROP Table Table, TempTable;

holmlund
Contributor III
Contributor III
Author

Thank you very much Sunny. Learned a lot from this...

sunny_talwar

No problem at all... I am glad I was able to help you learn

Best,

Sunny