I am a beginner concerning SOQL, I hope you can help me.
I would like to combine these two queries:
Query 1:
SELECT Id, Category__c, Segment__c
FROM Account
WHERE (Category__c = 'Prospect' AND Segment__c = 'High') OR (Category__c = 'Referrer' AND Segment__c = 'High')
Query 2:
SELECT Account_vod__c, WEEK_IN_YEAR(Call_Date_vod__c), CALENDAR_YEAR(Call_Date_vod__c)
FROM Call2_vod__c
WHERE Call_Date_vod__c = LAST_N_WEEKS:7
GROUP BY Account_vod__c, Call_Date_vod__c
Where the id of Account should equal the Account_vod__c value from Call2_vod__c.
When I combine these, I get something as:
Combined Query:
SELECT Id, Category__c, Segment__c
FROM Account
WHERE id in (select Account_vod__c from Call2_vod__c where Call_Date_vod__c = LAST_N_WEEKS:7) AND ((Category__c = 'Prospect' AND Segment__c = 'High') OR (Category__c = 'Referrer' AND Segment__c = 'High'))
But now I am missing the Week and Year values:
WEEK_IN_YEAR(Call_Date_vod__c), CALENDAR_YEAR(Call_Date_vod__c)
and this part:
GROUP BY Account_vod__c, Call_Date_vod__c
How Can I combine these queries and display the right week and calendar data?
Thanks!
If your Account_vod__c is a lookup to Account object, you can fetch fields from Account by typing Account_vod__r.Name etc (with "r" instead of "c" and using a dot).
So try with something like this?
SELECT Account_vod__c, Account_vod__r.Category__c, Account_vod__r.Segment__c, WEEK_IN_YEAR(Call_Date_vod__c), CALENDAR_YEAR(Call_Date_vod__c)
FROM Call2_vod__c
WHERE Call_Date_vod__c = LAST_N_WEEKS:7
GROUP BY Account_vod__c, Account_vod__r.Category__c, Account_vod__r.Segment__c, WEEK_IN_YEAR(Call_Date_vod__c), CALENDAR_YEAR(Call_Date_vod__c)
A similar one that should work for everybody who doesn't have your objects:
SELECT AccountId, Account.Name, COUNT(Id) countOfContactsCreatedThatWeek, WEEK_IN_YEAR(CreatedDate) week, CALENDAR_YEAR(CreatedDate) year
FROM Contact
GROUP BY AccountId, Account.Name, WEEK_IN_YEAR(CreatedDate), CALENDAR_YEAR(CreatedDate)
If you're ok with using two queries, I would start with that. In the combined version you have, you're technically calling two queries anyways. The inner query in the where clause counts as a second query against your governor limits.
If you're using Apex, try:
Map<Id, Account> aMap = new Map<Id, Account>([SELECT Id, Category__c, Segment__c
FROM Account
WHERE (Category__c = 'Prospect' AND Segment__c = 'High') OR (Category__c = 'Referrer' AND Segment__c = 'High')]);
List<Call2_vod__c> callList = [SELECT Account_vod__c, WEEK_IN_YEAR(Call_Date_vod__c), CALENDAR_YEAR(Call_Date_vod__c)
FROM Call2_vod__c
WHERE Call_Date_vod__c = LAST_N_WEEKS:7 and Id in :aMap.keySet()
GROUP BY Account_vod__c, Call_Date_vod__c];
Related
I am struggling with joining the below two queries.
My main query is the first one below and what I am trying to achieve is the output of query 2's opt in rate column as a new column in my original query.
SELECT CAST("public"."event_event"."date_created" AS date) AS "date_created", "marketing_message__via__messag"."name" AS "name", count(*) AS "count"
FROM "public"."event_event"
LEFT JOIN "public"."marketing_message" "marketing_message__via__messag" ON "public"."event_event"."message_id" = "marketing_message__via__messag"."id" LEFT JOIN "public"."marketing_campaign" "marketing_campaign__via__campa" ON "public"."event_event"."campaign_id" = "marketing_campaign__via__campa"."id"
WHERE (date_trunc('month', CAST("public"."event_event"."date_created" AS timestamp)) = date_trunc('month', CAST(now() AS timestamp))
AND "marketing_message__via__messag"."name" IS NOT NULL AND ("marketing_message__via__messag"."name" <> ''
OR "marketing_message__via__messag"."name" IS NULL) AND "public"."event_event"."stage" = 'Lead' AND ("marketing_campaign__via__campa"."name" = 'a'
OR "marketing_campaign__via__campa"."name" = 'b'
OR "marketing_campaign__via__campa"."name" = 'c'
OR "marketing_campaign__via__campa"."name" = 'c1' OR "marketing_campaign__via__campa"."name" = 'd'
OR "marketing_campaign__via__campa"."name" = 'e'))
GROUP BY CAST("public"."event_event"."date_created" AS date), "marketing_message__via__messag"."name"
ORDER BY CAST("public"."event_event"."date_created" AS date) ASC, "marketing_message__via__messag"."name" ASC
I would like to add the following query output for "Opt-In rate" to my query above as a new column.
Query 2
SELECT marketing_message.message_text,
cast(sum((event_event.status='Opt-in')::int) as decimal) / nullif(sum((event_event.status='Sent')::int), 0)* 100 as "Opt-in Rate (Sent)"
FROM event_event
JOIN marketing_campaign ON event_event.campaign_id = marketing_campaign.id
JOIN marketing_message ON event_event.message_id = marketing_message.id
WHERE True [[AND {{campaign_name}}]] [[AND {{date_created}}]]
GROUP BY marketing_message.message_text
The short answer is that you can't.
Your first query is keyed on date and name (the GROUP BY clause) and your second query is keyed on message_text. As there is no relationship between the two datasets there is no way of joining/combining them in a single query.
You would need to find a common field (or fields) between the two datasets and join on them - but this won't give the same results that you have at the moment as your queries would need to be completely restructured.
I need to join two queries output of 1st query should be the input for 2nd query in where clause, How do I achieve this?
Select
Distinct
TRNSFR_SRC_ID,
DESCR_ORG,
SUBJECT,
CRSE_NBR,
DESCR1_FRMVW,
SUBJECT_TO,
CATALOG_NBR_TO,
FROM
TRNSFR_CRSE
WHERE
ORG_ID = ?
Select
Distinct
ATTR_VALUE
From TRNSFR_CRSE
Where
ORG_ID = ?
and SUBJECT = ?
and CRSE_NBR = ?
and SUBJECT_TO = ?
and CATALOG_NBR_TO = ?
and CRSE_ATTR = 'GHH'"
Oracle can make this really easy, but I'm not sure how to apply it in this case. But something like this:
select Distinct ATTR_VALUE
from TRNSFR_CRSE
where (ORG_ID, SUBJECT, CRSE_NBR, SUBJECT_TO, CATALOG_NBR_TO) IN
(Select TRNSFR_SRC_ID, SUBJECT, CRSE_NBR, SUBJECT_TO, CATALOG_NBR_TO
from TRNSFR_CRSE
where ORG_ID = ?
) and
CRSE_ATTR = 'GHH'
You can use = rather than in if you know the subquery is supposed to return no more than one row.
If I assume that the output of the 1st query is input to the second query then use below
Select
Distinct
ATTR_VALUE
From TRNSFR_CRSE
Where
(ORG_ID,SUBJECT,CRSE_NBR,SUBJECT_TO,,CATALOG_NBR_TO) in
(Select
DESCR_ORG,
SUBJECT,
CRSE_NBR,
SUBJECT_TO,
CATALOG_NBR_TO,
FROM
TRNSFR_CRSE
WHERE
ORG_ID = ?)
and CRSE_ATTR = 'GHH'"
I am trying to get the total count for a specific "COMPONENT_DATA_POINT"."NAME" as it relates to the "DATA_POINT_UPLOAD_DATA"."VALUE". For example, here is my current query:
select "DATA_POINT_UPLOAD_DATA"."VALUE" as "EQUIP_ONLINE_VALUE"
from "DB"."DATA_POINT_UPLOAD_DATA" "DATA_POINT_UPLOAD_DATA"
where
"DATA_POINT_UPLOAD_DATA"."COMPONENT_UPLOAD_DATA_ID" IN (select id from (select "COMPONENT_UPLOAD_DATA".* from "DB"."COMPONENT_UPLOAD_DATA" "COMPONENT_UPLOAD_DATA",
"DB"."COMPONENT" "COMPONENT"
where
"COMPONENT_UPLOAD_DATA"."DATA_COLLECTED_TIME" < CURRENT_DATE
and "COMPONENT_UPLOAD_DATA"."COMPONENT_NO"='1'
and "COMPONENT_UPLOAD_DATA"."SITE_UPLOAD_DATA_SITE_ID"="COMPONENT"."SITE_ID"
and "COMPONENT_UPLOAD_DATA"."COMPONENT_ID"="COMPONENT"."ID"
and "COMPONENT"."COMPONENT_TYPE_ID" = '123'
and "COMPONENT"."SITE_ID" in ('123ABC')
ORDER BY "COMPONENT_UPLOAD_DATA"."DATA_COLLECTED_TIME" DESC)
where rownum <= 1)
and "DATA_POINT_UPLOAD_DATA"."COMPONENT_DATA_POINT_ID" IN (select COMPONENT_DATA_POINT_ID from (select "DATA_POINT_UPLOAD_DATA".*
from "DB"."COMPONENT_DATA_POINT" "COMPONENT_DATA_POINT",
"DB"."DATA_POINT_UPLOAD_DATA" "DATA_POINT_UPLOAD_DATA",
"DB"."COMPONENT" "COMPONENT"
where "DATA_POINT_UPLOAD_DATA"."COMPONENT_DATA_POINT_ID"="COMPONENT_DATA_POINT"."ID"
and "COMPONENT_DATA_POINT"."NAME" ='EquipUp'
and "COMPONENT_DATA_POINT"."COMPONENT_ID" = "COMPONENT"."ID"
and "COMPONENT"."COMPONENT_TYPE_ID" = '123'
and "COMPONENT"."SITE_ID" in ('123ABC')));
Current output I believe only shows one count, and not a total sum of all 'EquipUp':
EQUIP_ONLINE_VALUE
------------------------
1
I would like to get a total 'EQUIP_ONLINE_VALUE' sum of all 'EquipUp' names.
Any help would be greatly appreciated.
Thanks.
You do not have a count / sum function in your query.
Your where clause only returns 1 row, which has a DATA_POINT_UPLOAD_DATA.VALUE
of 1.
Are you sure your rownum <= 1 is correct?
Try running each section in your where clause individually to determine whether they
bring back multiple rows of data.
If you require the sum of each
EquipUp, use a SUM(value) from... group By COMPONENT_DATA_POINT.NAME
Run these 2 scripts to determine you have the correct data to begin with:
SELECT "COMPONENT_UPLOAD_DATA".*
FROM "DB"."COMPONENT_UPLOAD_DATA" "COMPONENT_UPLOAD_DATA"
,"DB"."COMPONENT" "COMPONENT"
WHERE "COMPONENT_UPLOAD_DATA"."DATA_COLLECTED_TIME" < CURRENT_DATE
AND "COMPONENT_UPLOAD_DATA"."COMPONENT_NO" = '1'
AND "COMPONENT_UPLOAD_DATA"."SITE_UPLOAD_DATA_SITE_ID" = "COMPONENT"."SITE_ID"
AND "COMPONENT_UPLOAD_DATA"."COMPONENT_ID" = "COMPONENT"."ID"
AND "COMPONENT"."COMPONENT_TYPE_ID" = '123'
AND "COMPONENT"."SITE_ID" IN ('123ABC')
ORDER BY "COMPONENT_UPLOAD_DATA"."DATA_COLLECTED_TIME" DESC
SELECT "DATA_POINT_UPLOAD_DATA".*
FROM "DB"."COMPONENT_DATA_POINT" "COMPONENT_DATA_POINT"
,"DB"."DATA_POINT_UPLOAD_DATA" "DATA_POINT_UPLOAD_DATA"
,"DB"."COMPONENT" "COMPONENT"
WHERE "DATA_POINT_UPLOAD_DATA"."COMPONENT_DATA_POINT_ID" = "COMPONENT_DATA_POINT"."ID"
AND "COMPONENT_DATA_POINT"."NAME" = 'EquipUp'
AND "COMPONENT_DATA_POINT"."COMPONENT_ID" = "COMPONENT"."ID"
AND "COMPONENT"."COMPONENT_TYPE_ID" = '123'
AND "COMPONENT"."SITE_ID" IN ('123ABC')
below is a CTE that is part of a larger query. I am trying to attempt something simple: update or replace all records for '2016-11' or '2016-12' values with '2016-10.'
The query runs into an error at UPDATE. Is there an alternative here that would make this query work?
with q (month, cobrand, members) as
(select date_trunc('month',optimized_transaction_date), cobrand_id,
count(distinct unique_mem_id)
from yi_fourmpanel.card_panel
Where (cobrand_id = '10001372' or cobrand_id = '10005640' or cobrand_id = '10005244')
group by 1,2)
UPDATE q
SET members = dc
FROM (SELECT cobrand, members dc
FROM q
WHERE month = '2016-10') x
WHERE q.cobrand = x.cobrand
AND month IN ('2016-11', '2016-12')
If you don't want to change table data, don't use UPDATE.
To achieve what you want to do, write the main query similar to this:
WITH q(month, cobrand, members) AS (...)
SELECT
month,
cobrand,
CASE WHEN month IN ('2016-11', '2016-12')
THEN (SELECT members
FROM q q1
WHERE q1.month = '2016-10')
ELSE members
END
FROM q;
I can not figure it out:
I have a table called ImportantaRecords with fields like market, zip5, MHI, MHV, TheTable and I want to group all the records by zip5 that have TheTable = 'mg'… I tried this :
select a.Market,a.zip5,count(a.zip5),a.MHI,a.MHV,a.TheTable from
(select * from ImportantaRecords where TheTable = 'mg') a
group by a.Zip5
but it gives me the classic error with not an aggrefate function
and then I tried this:
select Market,zip5,count(zip5),MHI,MHV,TheTable from ImportantaRecords where TheTable = 'mg'
group by Zip5
and the same thing…
any help ?
You did not state what database you are using but if you are getting an error about columns not being in an aggregate function, then you might need to add the columns not in an aggregate function to the GROUP BY:
select Market,
zip5,
count(zip5),
MHI,
MHV,
TheTable
from ImportantaRecords
where TheTable = 'mg'
group by Market, Zip5, MHI, MHV, TheTable;
If grouping by the additional columns alters the result that you are expecting, then you could use a subquery to get the result:
select i1.Market,
i1.zip5,
i2.Total,
i1.MHI,
i1.MHV,
i1.TheTable
from ImportantaRecords i1
inner join
(
select zip5, count(*) Total
from ImportantaRecords
where TheTable = 'mg'
group by zip5
) i2
on i1.zip5 = i2.zip5
where i1.TheTable = 'mg'