Here is my SOQL problem.
Query 1:
Select
c.Date_Joined__c,
c.Email,
c.FirstName,
c.LastName,
c.regcode__c
from Contact c WHERE c.regcode__c ='XXXXXXXXX'
Query 2:
Select
p.Account__c,
p.Date__c,
p.Points__c,
p.Description__c,
p.Code__c
from Points__c p where p.Account__c ='YYYYYYYYYYYY' and (p.Points__c > 0)
Order by p.Date__c DESC
The relationship between the two queries is that c.regcode__c will have the same value as p.Code__c.
I want to combine Query1 and Query2, so c.regcode__c = p.Code__c
I'm stuck, I can't seem to get the syntax right for SOQL.
Is it even possible to do joins in the API?
You can't really create a join per se but you can do some filtering using a syntax similar to this:
SELECT Id FROM Contact WHERE c.RegCode__c IN (SELECT p.Code__c FROM Account)
As long as the subquery in the WHERE clause is only returning a single value and codes is a filterable field this should work. Also, this doesn't work if you were trying to filter by the same object (i.e. Account to Account). You can add more criteria to the account side to match your example queries.
Again, this isn't a true join so you can't put the account fields from your subquery. But you can at least filter down your contacts.
Related
I'm new to SalesForce and SOQL and was surprised that simple JOIN can become a real problem for me.
There are 2 Tables (Account and Intake__c) that I want to INNER JOIN. The only data I need from Account Table is Client Name (Name).
I was able to run 2 queries separately with no errors.
Account:
SELECT
a.Id,
a.Name
FROM Account AS a
Intake__c:
SELECT
i.Client_Id__c,
i.Intake_Id__c,
i.Intake_Name__c,
i.Intake_Status__c
FROM Intake__c AS i
However, when I try to join them, I get the error:
MALFORMED_QUERY: ERROR at Row:1:Column:151 unexpected token: 'JOIN'
SELECT
i.Client_Id__c,
a.Name,
i.Intake_Id__c,
i.Intake_Name__c,
i.Intake_Status__c
FROM Intake__c AS i
JOIN Account AS a
ON (i.Client_Id__c = a.Id)
SOQL syntax for joins is special, looks bit object-oriented. https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_relationships_and_custom_objects.htm
You probably need
SELECT Client_Id__r.Name, Intake_Id__c, Intake_Name__c, Intake_Status__c
FROM Intake__c
The "__r" bit is called relationship name and acts bit like a table alias in JOIN. You can travel via "dot" up to 5 times (see, "object-oriented").
And if you'd need a top-down approach (left outer join starting from account) it'd probably be something like
SELECT Id, Name,
(SELECT Intake_Status__c FROM Intakes__r)
FROM Account
Is there a way to return multiple rows in a SQL select clause, when your subquery does not have a join/key field? My query currently looks like this. I'm wanting to return list of users and a list of contracts when there is no key between the users and contracts.
There is a handful of users, but a whole lot of contracts and I'm wanting to generate a list of each contractID next to each userID.
select
userid,
(select contractid from contracts) as contractid
from users
New here, but the suggestion for a cross join did what I wanted. thanks!
You can generate all possible combinations of users with constracts by performing a CROSS JOIN. For example:
select
u.*,
c.*
from users u
cross join contracts c
You can, then, filter the result by appending WHERE <condition> as needed.
I have two tables Author and Book with relationship one-many.
Now I want to list all authors with total of books in a particular country.
I use SQL Sever, this is my query.
SELECT Author.id, Author.name, Author.age, subTbl.total
FROM Author INNER JOIN (SELECT Book.authorId, COUNT(*) AS total FROM Book GROUP BY Book.authorId) subTbl
ON Author.authorId = subTbl.authorId
WHERE Author.countryId = 'en';
I know that we can write this query in another way without using SubQuery but I want to try SubQuery with CriteriaQuery to write this query.
I have searched further, but there are only examples of SubQuery in where expression.
I have to write a query regarding the statement below:
List all directors who directed 50 movies or more, in descending order of the number of movies they directed. Return the directors' names and the number of movies each of them directed.
I have written multiple variations but I keep getting errors.
It involves joins. The tables involved are:
Directors (directorID, firstname, lastname),
Movie_Directors (directorID, movieID).
What I have tried so far is:
SELECT DISTINCT
firstname, lastname,
COUNT(movie_directors.directorID)
FROM
dbo.movie_directors
INNER JOIN
directors ON directors.directorID = movie_directors.directorID
GROUP BY
firstname, lastname
HAVING
COUNT(movie_directors.directorID) >= 50
Is this correct?
Whenever you use a GROUP BY, any column not in an aggregate function MUST be in the GROUP BY clause MSDN - Group By (Transact SQL).
The reasoning is this: a GROUP by smashes records by the unique sets of values of each column in the group by, so any column not in the GROUP BY or HAVING clause would be outside of the purpose of a group by.
So by forcing an aggregate function for the columns, we guarantee the select statement is purposeful in its results...which should be how you code anyways.
Also, COUNT() ignores NULL values anyways and your ON predicate will only return on matches between the two tables on the director_ID. INNER JOIN will not return null results.
So use use a COUNT(<group by colum>) in your select statement.
Lastly, your HAVING clause is another predicate and can only be used with a GROUP BY.
MSDN - HAVING (Transact-SQL)
I'm trying to write a query in PostgreSQL and I'm getting a little frustrated because it works in other database engines. I need to select the top 5 users from a given joins table like this:
SELECT users.*,
COUNT(deals.id) AS num_deals
FROM users, deals
WHERE deals.users_id = users.id
GROUP BY users.id
ORDER BY num_deals LIMIT 5;
I need the top 5 users. This code works in sqlite, mysql, etc, yet PostgreSQL refuses to select additional fields that aren't used in aggregate functions. I'm getting the following error:
PGError: ERROR: column "users.id" must appear in the GROUP BY clause or be used in an aggregate function
How can I do this in PostgreSQL??
You could try:
SELECT users.*, a.num_deals FROM users, (
SELECT deal.id as dealid, COUNT(deals.id) AS num_deals
FROM deals
GROUP BY deal.id
) a where users.id = a.dealid
ORDER BY a.num_deals DESC
LIMIT 5
Assuming that users.id IS a PK, then you can either
wait for 9.1
group by all fields
use an aggregate (i.e. max() ) on all fields
One other solution that works is to use all attributes implicitly in GROUP BY
Thus following will be final query
SELECT users.*,
COUNT(deals.id) AS num_deals
FROM users, deals
WHERE deals.users_id = users.id
GROUP BY users.id, users.name, users.attrib1, ..., users.attribN
ORDER BY num_deals LIMIT 5;
If you are using framework like rails then you can implement this easily with Model.column_names function.
Just in case of somebody wants ANSI-92 standard solution and doesn't like 'Oracle' way to join tables...
SELECT users.*, num_deals
FROM users
JOIN
(SELECT deals.users_id as users_id, count(deals.users_id) as num_deals
FROM deals
GROUP BY deals.id) grouped_user_deals
ON grouped_user_deals.users_id = users.id
ORDER BY num_deals DESC
LIMIT 5;