Salesforce SOQL Query to access a child field in WHERE statement - salesforce

I am attempting to write a query on an object, Opportunity, this object has a child object Quotes.
In Quotes where have a field named, Order_Ready.
What I need to do is filter in all opportunities that have approved quotes (Order_Ready__c == true).
Here is the query I have been attempting to get working,
SELECT Id, Name (SELECT Order_Ready__c FROM Quotes) FROM Opportunity WHERE Opportunity.Quotes.Order_Ready__c = true
I have tried a few variations of this,
SELECT Id, Name (SELECT Order_Ready__c FROM Quotes) FROM Opportunity WHERE Quotes.Order_Ready__c = true
SELECT Id, Name (SELECT Order_Ready__c FROM Quotes) FROM Opportunity WHERE Order_Ready__c = true
I have to admit, I'm not the strongest with SQL/SOQL. Any insight into where my mistake or misunderstanding might be?
Thanks!

SELECT Id, Name FROM Opportunity WHERE Id IN
(Select OpportunityId FROM Quote WHERE Order_Ready__c = true)

Related

Child to Parent SOQL Query

I need a query between Opportunity and OpportunityLineItem.
OpportunityLineItem has a lookup for Opportunity. Child relationship name is OpportunityLineItems. Opportunity Lookup field is called OpportunityId.
I'm trying the below query but it doesn't work.
select Id,Name,OpportunityId__r.Description from OpportunityLineItem
Also tried:
select Id,Name,OpportunityLineItems__r.Description from OpportunityLineItem
Top-down
SELECT Id, Name, Description,
(SELECT Id, Name FROM OpportunityLineItems)
FROM Opportunity
Bottom-up
SELECT Id, Name, Opportunity.Name, Opportunity.Description
FROM OpportunityLineItem
Check out the links in https://stackoverflow.com/a/73913839/313628 and https://stackoverflow.com/a/73877986/313628 too

ORDER BY select statement using UNION & DISTINCT

I'm using the following query to populate a dropdown list of values.
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
I'd like to sort A-Z the results. I've tried the following:
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
ORDER BY City ASC
But am getting an error:
Incorrect syntax near the keyword 'Union'.
Additionally this query is pulling "Blank or NULL" values and displaying a blank space at the top of the drop-down. I'd like to hide that if possible. Not display any null value?
You want to add a row to your result, which is always on top and carries a NULL as ID?
Try this:
SELECT *
FROM
(
SELECT NULL AS col1,'select an object' AS col2,0 AS SortInx
UNION ALL
SELECT TOP 10 object_id,name,ROW_NUMBER() OVER(ORDER BY name)
FROM sys.objects
) AS Sortable
ORDER BY SortInx
Short explanation: ROW_NUMBER() start with 1, so the first row gets 0 as sort index. The numbers from 1 to x represent the sorted name's order.
The outer SELECT will sort the result-set again making sure, that 0 is in front and 1 to x following...
I agree with most of the comments here where the best approach is to actually have the "Select a Value" row added in the application itself. It's probably best to have the database only delivering "actual" data to your application and handle things like that in the code.
I'm also not sure what this project is for, but if you have access, I would strongly recommend creating views and/or stored procedures at the database level to abstract any database schema and logic changes from your application.
Just out of curiosity, why are you selecting the same field twice with different aliases? I'm assuming you're setting the display value and the actual value in a simple HTML dropdown, but in this case, the values are the same, so you could only have one field in your result set and reference that value twice in the application. Doing this would solve the problem of your original question, as well as simplify your query (although a query this simple is going to have negligible cost anyway) to look like this:
SELECT DISTINCT City
FROM BND_Listing (NOLOCK)
WHERE City IS NOT NULL
ORDER BY 1 ASC
Depending on the data, DB config, etc, you may need to account for empty strings and/or leading/trailing spaces with something like this:
SELECT DISTINCT LTRIM(RTRIM(City)) AS City
FROM BND_Listing (NOLOCK)
WHERE LTRIM(RTRIM(City)) <> ''
AND City IS NOT NULL
ORDER BY 1
Sorry...I know that may have been a little overkill, but you said you were new to SQL, so I thought I'd just share that in case your NULL results were actually empty strings.
Thank you everyone for the responses it gave me a lot of insight on where to look for my problem. The original query with the addition of the below achieved the proper result.
working query:
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
where isnull(City,'') <> ''
Order by City ASC
with 'Select a City' always at the top of the dropdown. Credit to #scsimon on my other post for this.
with cte as(
select 'Select a City' as City, 'All' as Value
UNION ALL
select distinct City, City as Value from BND_Listing
where isnull(City,'') <> '')
select * from cte Order by case when City = 'Select a City' then 1 else 2 end, City ASC

Alternative to multiple AND operator

is there a cleaner(better) alternative to using multiple AND operator in T-sql.
for example
use Portal
go
SELECT
U.Id,
U.FirstName,
U.LastName,
U.Email,
U.Gender,
U.Country
FROM AspNetUsers U
WHERE (U.M01 >= 80 and U.M02 >= 80 and u.M03 >= 80 AND U.M04 >= 80)
If AND is what you need then AND is the proper operator.
AND is efficient as it can give up as soon as it gets a single false.
The query optimizer is (typically) smart enough to look for the easy false first.
OR is not as efficient so some times you will refactor to get rid of the OR but I have never had a reason to refactor an AND.
If the value changes then maybe go with this for convenience but it should not effect execution
declare #count int = 80;
SELECT
U.Id,
U.FirstName,
U.LastName,
U.Email,
U.Gender,
U.Country
FROM AspNetUsers U
WHERE U.M01 >= #count
and U.M02 >= #count
and u.M03 >= #count
AND U.M04 >= #count;
No, if result depends on columns that you have in WHERE. If there will be good index it will be fast too (good index for this query is
create index [some name] on AspNetUsers (M01, M02, M03, M04) include (Id, FirstName, LastName, Email, Gender, Country)
But this query looks strange and probably it is problem with design/normalization
There are few options to simplify this particular selection syntax but it is hard to say if they make sense without knowing your entire context and your definition of better/cleaner...
Let's assume that cleaner/better means "selection without conjunction operators" for you.
Some of possible options:
Create a view that will prefilter your AspNetUsers table. Then your query syntax could be simplified to:
SELECT
Id,
FirstName,
LastName,
Email,
Gender,
Country
FROM AspNetUsersPerfiltered
Move filtering logic to dedicated function that will check the condition. Then your query syntax could be simplified to:
SELECT
Id,
FirstName,
LastName,
Email,
Gender,
Country
FROM AspNetUsers
WHERE myFunction(M01, M02, M03, M04) = 1
Create additional column(flag) that will be set during row insert/update or by some background process. Then your query syntax could be simplified to:
SELECT
Id,
FirstName,
LastName,
Email,
Gender,
Country
FROM AspNetUsers
WHERE FlagColumn = 1
HTH

Salesforce REST API SOQL get account for opportunies

I want to do a query for all my opportunities (or contacts or whatever) and then join in the account so I can get the name etc. I'm able to get it to work querying accounts and joining the opportunities, but not the other way around.
select Name, Id, (select Id, Name, CloseDate, StageName, Amount from Opportunities where ownerId = 'id') from Account
Is there a way to do the query on opportunities instead? I don't want to get all accounts and loop through to get the opportunity data. Should be a simple belongs to type relationship.
I've tried such queries as:
select Id, Name, CloseDate, StageName, Amount, (select Name, Id from Account) from Opportunity where ownerId = 'id'
But that gives me "Didn't understand relationship 'Account' in FROM part of query call."
Thanks!
For child->parent relationships you just use a dotted path to the fields you want, e.g.
Select id, Amount, CloseDate, Account.Name from Opportunity

PostgreSQL subselect problem

When I try to do the select statement, I always get the following error:
ERROR: more than one row returned by a subquery used as an expression
Only if there's only one result, it works. Why and how to fix?
SELECT name from person p where
id = ( select prs from leader
where age(leader.lastcourse) > '1 year');
You are trying to assign one particular ID from a select that seems to be returning multiple ID's. OrbMan's solution will take the first ID, randomly, from the subquery. If you want ALL ID's that meet the subquery condition,
SELECT name from person p where
id IN ( select prs from leader
where age(leader.lastcourse) > '1 year');
Mark's approach to use a JOIN rather than subquery also works.
It makes no sense to say that an integer is equal or not equal to a result set containing two rows. To do what you want you can choose between IN, EXISTS, or a JOIN. Here's how you can do it with a join:
SELECT name
FROM person p
JOIN leader
ON p.id = leader.prs
where age(leader.lastcourse) > '1 year'

Resources