3

I'm trying to figure out a way to get last inserted records according to distinct lookup field. Let's say I have data like this;


Field ----- Lookup ----- CreatedDate

Data1 ----- User1 ----- Inserted 5 min ago

Data2 ----- User2 ----- Inserted 6 min ago

Data3 ----- User2 ----- Inserted 7 min ago

Data4 ----- User1 ----- Inserted 8 min ago

Data5 ----- User3 ----- Inserted 10 min ago


And I have distinct Lookup field Set like {User1,User2,User3}

I want to get data that highlighted with bold. Is it possible? Because getting data ordered by CreatedDate does not return what I need.

UPDATE: I know that I can grab records ordered by CreatedDate then inside a for I can get latest values for distinct fields. But I have a large data set. Because of this I need to avoid limits. But limiting to query, let's say 1000, might not always return record for every distinct lookup field. For User200 last inserted record might be 20 days ago. Then by limiting query to 1000 I might not get the record for User200.

7
  • Probably Select FieldName from ObjectName where Lookup in: distinctUserList OrderBy Createddate desc
    – Mr.Frodo
    Commented May 31, 2016 at 10:45
  • @Mr.Frodo No. That would return my sample data list. I just want bold part. I don't want two User1 in returned query result.
    – tugce
    Commented May 31, 2016 at 10:50
  • You really don't want to use apex ;)
    – Mr.Frodo
    Commented May 31, 2016 at 10:54
  • I don't understand what you mean with that comment.
    – tugce
    Commented May 31, 2016 at 10:57
  • I mean my query will return the records in order by createddate.Then by simply iterating it and checking the condition you can grab what you want.
    – Mr.Frodo
    Commented May 31, 2016 at 11:01

2 Answers 2

0

It would seem you can limit this in a couple of different ways. One is by number of records returned, another is by using TypeOf (see Working with Polymorphic Relationships & you would need to have this feature enabled in your org) as well as CreatedDate of either Yesterday, Today, or LAST_N_DAYS:n. See Date Formats and Date Literals for more.

list<User>ListofUsers = new list<User>();

[Select FieldName from ObjectName where TypeOf Lookup = 'User' && Lookup in: ListofUsers 
    && (Createddate > YESTERDAY && Createddate < Now()) Limit n];

Note: You can use DateTime with Date functions in SOQL query WHERE clauses. See Condition Expression Syntax (WHERE Clause).

3
  • Hi @crmprogdev, thanks for your answer. But I really don't want to narrow down numbers of record returned because I have a lot of data come in every minutes from x number of users. If data from A user does not come for some number of days I might lost it in narrowing down process.
    – tugce
    Commented May 31, 2016 at 14:38
  • You're going to need to put some kind of limit on the number of records returned so it doesn't exceed 50k. You do that partly by narrowing the WHERE criteria and then limit the number of days or weeks you want to see data from. Otherwise, you're going to hit the query size limit. Plus, do you really want to receive 50k of records? What are you going to do with them if you get that many?
    – crmprogdev
    Commented May 31, 2016 at 15:12
  • Btw, you can of course use OrderBy and GroupBy clauses on these as well.
    – crmprogdev
    Commented May 31, 2016 at 15:14
0

Well after a bit of thought and help of a colleague I find the solution like this (but I did not test it extensively, yet. For now it seems to work just fine). Solution uses MAX function of soql. After finding MAX value for each created date grouping by user (or lookup field) I re-query with data in hand. This returns last inserted records.

        //getting lookup fields
        List<User> users = new List<User>();
        users = [SELECT Id FROM User];
        Set<Id> userIds = (new Map<Id,User>(users)).keySet();

        //getting max createdDate for users
        List<AggregateResult> records = [SELECT CreatedById, MAX(CreatedDate) FROM ObjectName WHERE CreatedById IN :userIds GROUP BY CreatedById];

        //put dates in a list
        Set<Datetime> cDates = new Set<Datetime>();
        For(AggregateResult record : records){
            cDates.add(Datetime.valueOf(record.get('expr0')));
        }

        //finally get last record for each user (or lookup field)
        List<ObjectName> latestRecords = [SELECT Id, SomeField__c FROM ObjectName WHERE CreatedById IN :userIds AND CreatedDate IN :cDates];

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .