BookmarkSubscribe
Choose Language Hide Translation Bar
Highlighted
ileshem
Community Trekker

Add a group number to a DT based on a different DT.

Hello all,
I have two dt and I want to create a new column in the primary dt based on the data from the secondary dt.
I want a JSL command that check the date in "dt1" date column and match a group number from "dt2" based on the start and end date. (timeframe)

 

dt1: (primary)

dateGroup 
5/17/2019 13:06 
5/17/2019 13:06 
5/23/2019 10:02 
5/24/2019 13:47 

 

dt2: (secondary)

Groupstart dateend date
15/17/2019 20:155/18/2019 8:14
25/18/2019 8:155/18/2019 20:14
15/18/2019 20:155/19/2019 8:14
35/19/2019 8:155/19/2019 20:14
25/19/2019 20:155/20/2019 8:14
35/20/2019 8:155/20/2019 20:14
25/20/2019 20:155/21/2019 8:14
45/21/2019 8:155/21/2019 20:14
35/21/2019 20:155/22/2019 8:14
45/22/2019 8:155/22/2019 20:14
35/22/2019 20:155/23/2019 8:14
15/23/2019 8:155/23/2019 20:14
45/23/2019 20:155/24/2019 8:14
15/24/2019 8:155/24/2019 20:14

 

Your help will be highly appreciated.

0 Kudos
1 ACCEPTED SOLUTION

Accepted Solutions
julian
Staff

Re: Add a group number to a DT based on a different DT.

Hi again, @ileshem,

I mentioned you could solve this with custom jsl and wanted to share one way to do that with a few For() loops that work row by row through your primary table to find a date that meets your criteria in the secondary table. There are ways to do this more efficiently for very large applications but this is a start.

 

dt1 = Data Table( "primary.jmp" );
dt2 = Data Table( "secondary.jmp" );


For( i = 1, i <= N Row( dt1 ), i++, 

	For( j = 1, j <= N Row( dt2 ), j++, 
	
		If( And( dt1:date[i] >= dt2:Start Date[j], dt1:date[i] <= dt2:End Date[j] ),
			dt1:Group[i] = dt2:Group[j];
			Break();
		)
	
		
	)
	
);

 

@julian 

0 Kudos
3 REPLIES 3
julian
Staff

Re: Add a group number to a DT based on a different DT.

Hi @ileshem,

There are a few ways I would go about this. One way would be to create a table that lists the groups for every time point between the start and end date, and then you could use that table with Tables > Update to bring the group number in by matching directly on that new date column that spans the start and end. That would involve creating that new spanned table, and depending on how many date ranges you have that table could get pretty large. 

 

Another option (that I have a preference for in this case) is to use Tables > JMP Query Builder, which will allow us to establish a join that can use some SQL logic to match where a date is both after a start date but before the end date. You can design this query interactively, which is one reason I like this approach, so if you didn't want to script something, you could do it all with your mouse. Saving the script results in some jsl that isn't too hard to generalize, just requires some trickery to get just table names without extension, and to insert the table names using evalInsert(). A little strange, and others might have a more elegant way to do what I did here. That said, it's one way to go without writing some custom JSL to go row by row in one table to do the lookup in another (which is a third, and totally acceptable approach as well).

 

Here's the code for JMP Query Builder, and I attached your example tables for trying this out. If you're interested in how to set this up interactively let me know -- it takes all of 30 seconds to build this from scratch.

 

dt1 = Data Table( "primary.jmp" );
dt2 = Data Table( "secondary.jmp" );

dt1NameOnly = Left( dt1 << getname, Length( dt1 << getname ) - 4 );
dt2NameOnly = Left( dt2 << getname, Length( dt2 << getname ) - 4 );

New SQL Query(
	Version( 130 ),
	Connection( "JMP" ),
	JMP Tables( Eval Insert( "\[ [dt1<<getname => "_MEMORY_", dt2<<getname => "_MEMORY_"] ]\" ) ),
	QueryName( "SQLQuery1" ),
	Select( Column( "date", "t1", Numeric Format( "m/d/y h:m", "-1", "NO", "" ) ), Column( "Group 2", "t2" ) ),
	From(
		Table( dt1NameOnly, Alias( "t1" ) ),
		Table(
			dt2NameOnly,
			Alias( "t2" ),
			Join(
				Type( Left Outer ),
				GE(
					Column( "date", "t1", Numeric Format( "m/d/y h:m", "-1", "NO", "" ) ),
					Column( "Start Date", "t2", Numeric Format( "m/d/y h:m", "-1", "NO", "" ) )
				) & LE(
					Column( "date", "t1", Numeric Format( "m/d/y h:m", "-1", "NO", "" ) ),
					Column( "End Date", "t2", Numeric Format( "m/d/y h:m", "-1", "NO", "" ) )
				)
			)
		)
	)
) << Run;
julian
Staff

Re: Add a group number to a DT based on a different DT.

Hi again, @ileshem,

I mentioned you could solve this with custom jsl and wanted to share one way to do that with a few For() loops that work row by row through your primary table to find a date that meets your criteria in the secondary table. There are ways to do this more efficiently for very large applications but this is a start.

 

dt1 = Data Table( "primary.jmp" );
dt2 = Data Table( "secondary.jmp" );


For( i = 1, i <= N Row( dt1 ), i++, 

	For( j = 1, j <= N Row( dt2 ), j++, 
	
		If( And( dt1:date[i] >= dt2:Start Date[j], dt1:date[i] <= dt2:End Date[j] ),
			dt1:Group[i] = dt2:Group[j];
			Break();
		)
	
		
	)
	
);

 

@julian 

0 Kudos
ileshem
Community Trekker

Re: Add a group number to a DT based on a different DT.

Thanks allot!!
0 Kudos