Reply
Level: Powered On
Posts: 31
Registered: ‎04-04-2017

Re: Creating a join on 2 SQL Tables in the gallery

[ Edited ]

@Meneghino, thanks again for your time on this.

 

I seem to be making some progress. However, when I try to disambiguate the PartyNumber column in the lookup I get a warning.

 

Suggestion: Part of this lookup formula cannot be evaluated remotely due to service limitations. The local evaluation may produce suboptimal or partial results. I f possible, please try to simplify the formula. For more information, please see the Lookup function documentation.

 

This message appears under the disambiguation which is as follows.

LookUp('[dbo].[MemberShipDashBoardSTATIC]','[dbo].[MemberShipDashBoardSTATIC]'[@Partynumber]=PartyNumber, BDM)

 

I'm getting some results back now but the BDM field doesn't contain any results when it should.

Level 10
Posts: 1,490
Registered: ‎11-07-2016

Re: Creating a join on 2 SQL Tables in the gallery

Hi @greenawayr 

I think it is some performance issue, as indicated alo by the blue dot warning.  Some caching would really simplify your life, IMHO.

Level: Powered On
Posts: 31
Registered: ‎04-04-2017

Re: Creating a join on 2 SQL Tables in the gallery

[ Edited ]

OK @Meneghino,

 

I've cached the entriety of my two tables (not sure that's the right thing to do) and I'm still recieving an error

 

SortByColumns(Search(AddColumns('[dbo].[DIM_CustomerCRMCLONE]',"AccountBDM",LookUp('[dbo].[MemberShipDashBoardSTATIC]',RolesForCustomers.Partynumber in Profiles.PartyNumber, BDM)),TextSearchBox1.Text,"CustomerName"),"CustomerName",Ascending)

 

The error is Invalid argument type. Cannot use Table values in this context.

 

I also changed my "=" to an "in" and it gave me the error saying "Right side of "in" operator is not a column name.

 

Have I got confused about what a Lookup is capable of? I'm looking for this to do a SQL style join so that the columns in "RolesforCustomers" are appended to "Profiles" when their PartyNumbers are the same. I don't think the Lookup function is correct for this.

Level 10
Posts: 1,490
Registered: ‎11-07-2016

Re: Creating a join on 2 SQL Tables in the gallery

Hi @greenawayr

 

In order to do a join in PowerApps you need to add a column containing a table and then use the Ungroup function.

LookUp simply looks up a single record.  So what you should do is GroupBy the target table, do the LookUp and then Ungroup the result.  This way you don't even need the in operator.

Please see here: https://powerapps.microsoft.com/en-us/tutorials/function-groupby/

 

However, please be aware that GroupBy and Ungroup are not delegable functions (yet)

 

When you say you have cached the tables, then I assume you mean you loaded the tables as collections.

Then you should use these collections in your formulas and not the dbo tables.

 

I have lost a bit track of your table names and column names so it is difficult for me to give you a specific formula.  I will look back at your previous posts if you have not managed to get a working result.  Don't worry, we'll get there.

Highlighted
Level: Powered On
Posts: 31
Registered: ‎04-04-2017

Re: Creating a join on 2 SQL Tables in the gallery

Yes @Meneghino, Sorry my Data Warehouse guy has asked me to use different tables.

 

I have created collections for my two tables as suggested, so I have the following Collections:

 

- Profiles (The information about my customers, this is primary table containing the data the users want to see and edit the PartyNumber column is an identifier)

- Responsibilities (This table contains the BDM and the PartyNumber FK)

- I also have my collection called BDM that contains the current user Fullname

 

I think, I'm getting really close now.

 

I added a second button to build a collection that does the following

 

ClearCollect(Joined, AddColumns(Profiles, "BDM", LookUp(Responsibilities, PartyNumber=Profiles[@PartyNumber], BDM)))

 

That allows me to see the Collection has joined my two tables successfully (woohoo).

 

So now to my filter.

 

This is my one remaining issue. For the purposes of testing, I've created a 3rd button with the following:

 

ClearCollect(FilteredProfiles, Filter(Joined, First(UserBDM.Value) in Joined.BDM))

 

So create a Collection called FilteredProfiles by filtering the "Joined" collection created in the second button based on the Current User matching the BDM value.

 

Unfortunately this is my error

 

"Invalid argument type. Expecting a Record value, but of a different schema. Column 'BDM of type Text is missing."

 

If I remove the First() function around the UserBDM.Value then I get a complaint about using a table instead of a record.

 

If I get this last bit sorted I think I'm there. Would it then be possible to combine all these collection creations under one button and they execute in order or will it complain if it perform functions on collections in the same event that they are being created (i.e. the button click)?

 

Thanks again for this. Slowly getting my head around this.

Level: Powered On
Posts: 31
Registered: ‎04-04-2017

Re: Creating a join on 2 SQL Tables in the gallery

Argh!!!

 

Just found out about the 500 record limit in collections.

 

Not only does this mean my collections that should actually have thousands of records only return 500 records, but even if I were to filter direct on the SQL table, our BDM's can have over 500 customers so not sure how to architect this now!

 

Help please!

Level 10
Posts: 1,490
Registered: ‎11-07-2016

Re: Creating a join on 2 SQL Tables in the gallery

Hi @greenawayr

As mentioned (I think) in one of my previous replies, there are techniques for caching thousands of lines.  I have done this in a 3-4 seconds for 4,000 rows.  There is no limit to how many rows you can store in a collection, you just need to load them into the collection 500 rows at a time since that is the number that will be returned by any query.

 

I have a few posts where I mention the technique, but here is an example of what I use to cache up to 2,000 rows in 2-3 seconds:

 

ClearCollect(CachedInstruments, Sort('[dbo].[Instruments]', ID, Ascending));
UpdateContext({MaxID: Max(CachedInstruments, ID)});
If(CountRows(CachedInstruments)=500,
	Collect(CachedInstruments, Filter(Sort('[dbo].[Instruments]', ID, Ascending), ID > MaxID))
;
UpdateContext({MaxID: Max(CachedInstruments, ID)});
If(CountRows(CachedInstruments)=1000,
	Collect(CachedInstruments, Filter(Sort('[dbo].[Instruments]', ID, Ascending), ID > MaxID))
;
UpdateContext({MaxID: Max(CachedInstruments, ID)});
If(CountRows(CachedInstruments)=1500,
	Collect(CachedInstruments, Filter(Sort('[dbo].[Instruments]', ID, Ascending), ID > MaxID))
)))

 

Even if you have composite index in SQL Server (as you may for a many-to-many table), here is what I use for up to 2,500 rows:

 

ClearCollect(CachedEntitiesInstruments, SortByColumns('[dbo].[Entities_Instruments]', "Entity", Ascending, "Instrument", Ascending));
UpdateContext({MaxEntity: Max(CachedEntitiesInstruments, Entity), MaxInstrument: Max(CachedEntitiesInstruments, Instrument)});
If(CountRows(CachedEntitiesInstruments)=500,
	Collect(CachedEntitiesInstruments, Filter(SortByColumns('[dbo].[Entities_Instruments]', "Entity", Ascending, "Instrument", Ascending), (Entity = MaxEntity && Instrument > MaxInstrument) || Entity > MaxEntity))
;
UpdateContext({MaxEntity: Max(CachedEntitiesInstruments, Entity), MaxInstrument: Max(CachedEntitiesInstruments, Instrument)});
If(CountRows(CachedEntitiesInstruments)=1000,
	Collect(CachedEntitiesInstruments, Filter(SortByColumns('[dbo].[Entities_Instruments]', "Entity", Ascending, "Instrument", Ascending), (Entity = MaxEntity && Instrument > MaxInstrument) || Entity > MaxEntity))
;
UpdateContext({MaxEntity: Max(CachedEntitiesInstruments, Entity), MaxInstrument: Max(CachedEntitiesInstruments, Instrument)});
If(CountRows(CachedEntitiesInstruments)=1500,
	Collect(CachedEntitiesInstruments, Filter(SortByColumns('[dbo].[Entities_Instruments]', "Entity", Ascending, "Instrument", Ascending), (Entity = MaxEntity && Instrument > MaxInstrument) || Entity > MaxEntity))
;
UpdateContext({MaxEntity: Max(CachedEntitiesInstruments, Entity), MaxInstrument: Max(CachedEntitiesInstruments, Instrument)});
If(CountRows(CachedEntitiesInstruments)=2000,
	Collect(CachedEntitiesInstruments, Filter(SortByColumns('[dbo].[Entities_Instruments]', "Entity", Ascending, "Instrument", Ascending), (Entity = MaxEntity && Instrument > MaxInstrument) || Entity > MaxEntity))
))))

Please let me know if it is not clear how these work.

Level: Powered On
Posts: 17
Registered: ‎08-31-2017

Re: Creating a join on 2 SQL Tables in the gallery

Hello guys!

Did you find any solution?

Level: Powered On
Posts: 31
Registered: ‎04-04-2017

Re: Creating a join on 2 SQL Tables in the gallery

Creating collections and joining them as described above was the solution, however with the volume of data we were dealing with the process of "collecting" data into collections multiple times (up to 3000 rows), with the number of columns we had (around 100), this was very slow and was not a viable option for users who would be out and about with varying signal strength.

Level 10
Posts: 1,490
Registered: ‎11-07-2016

Re: Creating a join on 2 SQL Tables in the gallery

I think we will just have to wait for views to be available or for 'in' to be delegated.

Can't be long now, surely...