Inner Join Query

Posts   
 
    
half
User
Posts: 3
Joined: 09-Sep-2008
# Posted on: 09-Sep-2008 22:13:55   

How would I write the inner join to a query? (I know how to do the rest)

Select CustomerId, o.* From Customer as c inner join Order as o on c.customerid = o.customerid inner join (Select Max(OrderId) as MaxOId, CustomerId From Order Group By CustomerId) as t on o.orderid = t.MaxOId

jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 09-Sep-2008 23:02:32   

try this sql instead


select c.CustomerId, o.*
from Customer c inner join Order o on c.CustomerId=o.CustomerId
where o.OrderId in (select Max(OrderId) from Order group by CustomerId)

this is possible using a FieldSetPredicate (or some predicate like that). I know v2.0 doesn't support queries in the from clause. I think 2.5 does, but I try to avoid sub queries when possible.

half
User
Posts: 3
Joined: 09-Sep-2008
# Posted on: 09-Sep-2008 23:15:46   

I can't do it that way because I need the Max OrderId for each Customer

jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 10-Sep-2008 02:06:18   

why not try the query and see what the results are simple_smile

half
User
Posts: 3
Joined: 09-Sep-2008
# Posted on: 10-Sep-2008 02:14:56   

If I do it that way I will only get one row/result for Max OrderId for only one customer.

For Example

Customer Table
CustomerId
1
2
3
4

Order Table
OrderId CustomerId Total
1             1             $100
2             1             $150
3             2             $100
4             3             $100
5             4             $200
6             4             $120
7             4             $160

So my expected results are:
CustomerId OrderId Total
1                  2          $150
2                  3          $100
3                  4          $100
4                  7          $160

Doing it your way I get:
CustomerId OrderId Total
4                  7          $160
jmeckley
User
Posts: 403
Joined: 05-Jul-2006
# Posted on: 10-Sep-2008 03:46:19   
select max(id) from order

would give you 1 record: 7

select max(id) from order group by customerid

will give you 2, 3, 4 and 7 therefore

select c.customer, o.*
from customer c inner join order o on c.customerid = o.customerid
where o.orderid in (select max(orderid) from order group by customerid)

will give you the results you want

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Sep-2008 07:54:05   

I think Jason suggestions indeed works.

Anyway, you can write subquery relations using Derived Tables and Dynamic Relations:

// -- SUBQUERY AND DYNAMIC RELATION
// first specify the elements in the derived table select (which is a dyn. list)
ResultsetFields dtFields = new ResultsetFields(2);
dtFields.DefineField(OrdersFields.OrderId, 0, "OrderId", AggregateFunction.Max);
dtFields.DefineField(OrdersFields.CustomerId, 1);

// the grouper          
GroupByCollection dtGroupBy = new GroupByCollection(dtFields[1]);

// define the deriveTable
DerivedTableDefinition dtDefinition = new DerivedTableDefinition(dtFields, "MaxOrderByCustomer", null, dtGroupBy);

// then specify the relation. 
// derivedtable spec, join type, end entity type, alias first element, alias end element, on clause filter
DynamicRelation relation = new DynamicRelation(dtDefinition, JoinHint.Inner,
                    EntityType.OrdersEntity, "o",
                   (new EntityField2(OrdersFieldIndex.OrderId.ToString(), "MaxOrderByCustomer", typeof(int)) 
                    == OrdersFields.OrderId.SetObjectAlias("o")));


// -- THE RESULTS AND RELATIONS
// then define the results you want at top
ResultsetFields finalResulsetFields = new ResultsetFields(3);
finalResulsetFields.DefineField(CustomersFields.CustomerId, 0, "CustomerId", "c");
finalResulsetFields.DefineField(OrdersFields.OrderId, 1, "OrderId", "o");
finalResulsetFields.DefineField(OrdersFields.OrderDate, 2, "OrderDate", "o");

// relations
RelationPredicateBucket filter = new RelationPredicateBucket();
filter.Relations.Add(CustomersEntity.Relations.OrdersEntityUsingCustomerId, "c", "o", JoinHint.Inner);
filter.Relations.Add(relation);


// -- FETCH RESULTS
DataTable results = new DataTable();
using (DataAccessAdapter adapter = new DataAccessAdapter())
{
    adapter.FetchTypedList(finalResulsetFields, results, filter);
}

Above would generate something like:

SELECT 
    [LPA_c1].[CustomerID] AS [CustomerId], 
    [LPA_o2].[OrderID] AS [OrderId], 
    [LPA_o2].[OrderDate] 

FROM (
        ( [Northwind].[dbo].[Customers] [LPA_c1]  
            INNER JOIN [Northwind].[dbo].[Orders] [LPA_o2]  
                ON  [LPA_c1].[CustomerID] = [LPA_o2].[CustomerID]) 
            INNER JOIN (
                    SELECT 
                        MAX([Northwind].[dbo].[Orders].[OrderID]) AS [OrderId], 
                        [Northwind].[dbo].[Orders].[CustomerID] AS [CustomerId] 
                    FROM 
                        [Northwind].[dbo].[Orders]  
                    GROUP BY [Northwind].[dbo].[Orders].[CustomerID] ) [LPA_M3]  
                ON  [LPA_M3].[OrderId] = [LPA_o2].[OrderID])

You just need fix some typos on my code and it would work for sure.

David Elizondo | LLBLGen Support Team
Mri
User
Posts: 2
Joined: 20-Feb-2009
# Posted on: 20-Feb-2009 03:38:02   

I would like to know how to do a multi column sub query in llblGen.

e.g.

select * from Foo where (id, seq_nu) in (select id, max(seq_nu) from Foo group by id)

Please let me know if this is possible. Performance wise this the above is way more powerful than the alternate

select * from Foo a where a.seq_nu = (select max(seq_nu) from Foo b where a.id = b.id)

thanks

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Feb-2009 06:51:51   

AFAIK that's not possible. You can only work with

WHERE someField IN 
     (SELECT xxx FROM ...)

or

WHERE EXISTS 
     (SELECT .... FROM .... WHERE <the relation to the main query here)
David Elizondo | LLBLGen Support Team
Posts: 25
Joined: 16-Jul-2007
# Posted on: 21-Apr-2009 17:53:59   

Hi,

I'm trying to create a dynamic relation, like same way you have explained in your example. Here is my code

                    ResultsetFields EntityFields2 = new ResultsetFields(3);
                    EntityFields2.DefineField(EntityItemFields.EntityId, 0);
                    EntityFields2.DefineField(MetaDataFields.FieldId, 1);
                    EntityFields2.DefineField(MetaDataFields.MetaDataId, 2);

                    IPredicateExpression metdataFilter = new PredicateExpression(MetaDataFields.TaxonomyId == taxonomyId);
                    metdataFilter.AddWithAnd(MetaDataFields.FieldId == Constants.AVERAGE_ALLOCATION_SCORE_FIELDID);
                    metdataFilter.AddWithAnd(MetaDataFields.MetaDataId == EntityItemFields.MetaDataId);

                    DerivedTableDefinition metaTable = new DerivedTableDefinition(EntityFields2, "EI", metdataFilter);

                    HIA.BM.DAL.RelationClasses.DynamicRelation relation = new HIA.BM.DAL.RelationClasses.DynamicRelation(
                        metaTable, JoinHint.Left, HIA.BM.DAL.EntityType.EntitySetEntity, "ES",
                        (new EntityFields2(EntityItemFieldIndex.EntityId.ToString(), "EI", typeof(string)) == EntitySetFields.EntityId.SetObjectAlias("ES")));

My environment: VS IDE 2008, LLBLGEN version 2.6 latest build (2.6.09.0327)

But for some reason i'm getting following issues in compile time.

The best overloaded method match for 'HIA.BM.DAL.RelationClasses.DynamicRelation.DynamicRelation(SD.LLBLGen.Pro.ORMSupportClasses.DerivedTableDefinition, SD.LLBLGen.Pro.ORMSupportClasses.JoinHint, HIA.BM.DAL.EntityType, string, SD.LLBLGen.Pro.ORMSupportClasses.IPredicate)' has some invalid arguments    C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  306 75  HIA.BM.BL

Argument '5': cannot convert from 'bool' to 'SD.LLBLGen.Pro.ORMSupportClasses.IPredicate'   C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  308 26  HIA.BM.BL
The best overloaded method match for 'SD.LLBLGen.Pro.ORMSupportClasses.EntityFields2.EntityFields2(int, SD.LLBLGen.Pro.ORMSupportClasses.IInheritanceInfoProvider, System.Collections.Generic.Dictionary<string,int>)' has some invalid arguments   C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  308 26  HIA.BM.BL

Argument '1': cannot convert from 'string' to 'int' C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  308 44  HIA.BM.BL

Argument '2': cannot convert from 'string' to 'SD.LLBLGen.Pro.ORMSupportClasses.IInheritanceInfoProvider'   C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  308 86  HIA.BM.BL

Argument '3': cannot convert from 'System.Type' to 'System.Collections.Generic.Dictionary<string,int>'  C:\NextGen\BL\CollectionClasses\EntitySetCollection.cs  308 92  HIA.BM.BL

Please advise me how to proceed?

Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 22-Apr-2009 10:28:24   

You have posted this question in another new thread and I have replied to you, so lets proceed there.

ref: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=15791