Hot answers tagged

13

You can use a HAVING clause: AggregateResult[] results = [SELECT COUNT(Id) sum, Tool__c Id FROM Gear__c WHERE Tool__c = :tools GROUP BY Tool__c HAVING COUNT(Id) > 1]; This will give you a list of AggregateResult objects where the sum and Tool__c Id are given. You can even use the Map trick to get the count per record easily: Map<Id, AggregateResult&...


9

You're pretty close to a solution with your parent-child subquery. The big thing to realize is that, similar to how adding parent__r.someField__c gives you a real SObject instance nested in your query results, a parent-child subquery gives you a List<SObject> nested in your query results. About the only thing I'd add is to limit the subquery rows to ...


8

In Dynamic SOQL, you need to pay attention to spaces. There should be no space between : and what follows. Bad id NOT IN : setclosedId Good id NOT IN :setclosedId Spacing is important when building dynamic query strings, as the system is far less lenient in that case.


8

This type of code is tricky to bulkify, and some of the strategies that you'll use to do so depend on your knowledge of the expected data volume that will match each of the filters you're applying in your query. The basic principle is that you take your first object, demoObj1, and define the widest SOQL bounds you would need in order to match the right ...


8

This is just how the Developer console shows the details. It does not show any parent details but you are actually getting those details. List<Contact> contacts = [select id, name, AccountId, Account.Name, Account.Rating from Contact]; system.debug(contacts); for (Contact individualContact: contacts){ System.debug(individualContact.Account.Name)...


8

This occurs because of an optimization during the "query planning" phase of a query. The query optimizer removes null values from filters on required fields. This optimization allows Salesforce to use standard indexes instead of a full table scan on those fields, which can improve performance by many orders of magnitude on large tables. If Salesforce fixed ...


7

SOQL is a read only language. You cannot in any way use SOQL to perform write operations.


7

You have to use the child relationship name. You can always find it by using a script like the following: for (ChildRelationship relation : SObjectType.Contact.getChildRelationships()) if (relation.getChildSObject() == AccountContactRelation.sObjectType) system.debug(relation.getRelationshipName()); Paste the relationship name verbatim into ...


7

I am partial to stripInaccessible because WITH SECURITY ENFORCED because the queries throw an exception if any of the fields are not available to the user. I would not make it automatic to trigger execution, I would modify the triggers to pass this parameter. That will allow you to bypass FLS checks in other code that may need FLS bypassed (like an engine ...


6

Code a loop. But in general, you will need to build a Map<String, Set<Id>> unless you have duplicate rules that disallow duplicate Account names: Map<String, Set<Id>> m = new Map<String, Set<Id>>(); for (Account a : [ select Name, Id from Account where ... ]) { Set<Id> s = m.get(...


6

You can use SOQL Tooling api - can test from developer console: Also in older orgs you have objects ExternalString and ExternalStringLocalization which will give info on custom labels and also translated labels.


6

As stated in the SOAP API Documentation FieldPermissions : Represents the enabled field permissions for the parent PermissionSet. This object is available in API version 24.0 and later. So when querying the FieldPermissions object you'll only get the enabled permissions Possible solution 1- You should query the list of all fields of an SObject with ...


6

Since you already have a list of Ids (AcLst) you could query every Opportunity related to those Accounts, then populate a Map using the accountId as key and the list of opportunity as value. Map<Id, List<Opportunity>> mapAccountIdOpportunityList = new Map<Id, List<Opportunity>>(); for (Opportunity o : [SELECT Id, StageName, AccountId,...


6

I believe using selective query like IN is preferable over NOT IN. When your filter uses != or NOT—which includes using NOT EQUALS/CONTAINS for reports, even if the field is indexed—the Force.com query optimizer can’t use the index to drive the query. For better performance, filter using = or IN, and the reciprocal values. https://developer.salesforce....


5

You can use a filter without needing a variable, via LAST_N_DAYS: data = [SELECT LastModifiedDate FROM Account WHERE LastModifiedDate < LAST_N_DAYS:30]; This returns records that haven't been modified in 30 days. Also see Date Formats and Date Literals for other alternatives.


5

SOQL in Apex does not, by default, honor profile permissions. To do so, add WITH SECURITY_ENFORCED. As the documentation says: Apex generally runs in system context; that is, the current user's permissions, field-level security, and sharing rules aren’t taken into account during code execution. Although performing field- and object-level security checks ...


5

As mentioned by @benahm, SOQL on FieldPermissions retrieves only enabled field permissions for the permission set. Furthermore, as per chapter "Special Properties for Field Permissions" in documentation here, fields that are always readable and/or writable, don’t return a FieldPermissions record. Note that getDescribe methods can also be accessed via REST ...


5

Treat change set as an unmanaged package/manage package. You can extract all the metadata as a zip using the package name. Workbench already supports this and also the CLI You can use the Salesforce(sfdx) CLI to do this using below (It uses metadata api under the hood) sfdx force:mdapi:retrieve -s -r ./mdapipkg -u <username> -p <change set name>...


5

The GROUP BY makes the SOQL an aggregate query and the result must be a List<AggregateResult> See Apex doc on Aggregate queries That said, your trigger is not bulkified as you are doing SOQL inside of a for loop. See Trailhead on how to avoid this


5

My answer is that it doesn't matter for this example as the volume of data you are dealing with - 340 records - is small so optimization is way down the priorities. My priority list is ballpark this if there is nothing extreme about the code: Code that works Tests that prove the code works Code that doesn't run into query or CPU or heap governor limits Code ...


5

This syntax was not supported when building out the query language. Outside of that design team, few people will be able to answer the "why" of that question. However, the common workaround is to simply implement a formula which does the comparison for you, then filter on that formula instead. For example, your formula syntax would look like: ...


5

While I was composing this question I figured it out. Since it took me longer to figure out than I would have liked, I will share what I learned in case it helps someone else down the road. It turns out that the connection between CustomPermission and the PermissionSet is made via the object called SetupEntityAccess. You can look up if a custom ...


5

It should be bookMap.put instead of bookMap.add in your code. I don't see any other problem with your code.


5

If we use the second format then won't we end up with for loop inside a for loop because we need to read/process each and every record. Yes, but nested for loops aren't inherently evil and don't always need to be avoided at all costs. If you have a list of data that contains another list of data (easiest example is probably the result of a SOQL query that ...


5

It is interesting that the documentation that I've found doesn't explicitly state this scenario is covered, at least in the main text, where it says: The value of the IN or NOT IN operator in WHERE clauses, allowing filtering on a dynamic set of values. Note that this is of particular use with a list of IDs or Strings, though it works with lists of any type ...


5

You've got the right idea just the wrong syntax for the semi-join (not technically an inner query). Try this: List<Contact> conList = [ SELECT id, name FROM Contact WHERE id IN (SELECT contactId FROM Opportunity WHERE StageName = 'Closed Won') ];


4

The following should work. Set<Id> accountIdsWithOneInactive = new Map<Id, SObject>([ SELECT AccountId Id FROM AccountContactRelation WHERE IsActive = false GROUP BY AccountId HAVING count(Id) = 1 ]).keySet(); List<Account> records = [ SELECT Id FROM Account WHERE Id IN :accountIdsWithOneInactive AND Id NOT IN ( ...


4

As @Adrian said, SOQL is read only. However, Salesforce provides you with a way to do this when you have many records and you have Gov Limit concerns. It is called Batch Apex. You would create a class, define a query (which can be dynamic) and then iterate through the record. You can also, optionally, specify how big the batch is (ie: how many records get ...


4

According to what you said - The query works if I take off the pandadoc__PandaDocDocument__c. This is because Panda documents are child objects of Opportunity. So, you need inner query to get documents: SELECT Account.BillingStreet, (SELECT Id, Name, pandadoc__Account__c, pandadoc__Contact__c, pandadoc__Lead__c FROM pandadoc__Panda_Doc_Documents__r), (...


4

To paraphrase Bill Clinton, it depends on the definition of quickest For me, quickest means quickest to code as unless you have some CPU-sensitive transaction, your time is more valuable than SFDC server time. And this pattern occurs over and over again in your org. To that end, I built a small library of pivot methods that allow you to do this in one line ...


Only top voted, non community-wiki answers of a minimum length are eligible