I have two tables notifications and mailmessages.
Notifications table
- NotifyTime
- NotifyNumber
- AccountNumber
MailMessages table
- id
- messageSubject
- MessageNumber
- AccountNumber
My goal is to create a single sql query to retrieve distinct rows from mailmessages WHERE the accountnumber is a specific number AND the notifynumber=messagenumber AND ONLY the most recent notifytime from the notifications table where the accountnumbers match in both tables.
I am using sqlexpress2008 as a back-end to an asp.net page. This query should return distinct messages for an account with only the most recent date from the notifications table.
Please help! I'll buy you a beer!!!
Try this...
SELECT MM.MaxNotifyTime, Notify.MaxNotifyTime
FROM MailMessages MM
INNER JOIN (SELECT Max(NotifyTime) MaxNotifyTime, AccountNumber
FROM Notifications
GROUP BY AccountNumber) Notify ON (MM.AccountNumber=Notify.AccountNumber)
WHERE (MM.AccountNumber=1)
SELECT MM.MessageNumber, MAX(N.NotifyTime) MaxTime
FROM MailMessages MM
INNER JOIN Notifications N
ON MM.AccountNumber = N.AccountNumber AND MM.MessageNumber = N.NotifyNumber
WHERE MM.AccountNumber = 1
GROUP BY MM.MessageNumber
This limits to the given AccountNumber (=1) and outputs every associated MessageNumber together with the date of the most recent corresponding entry in Notifications.
Related
I am trying to create a SOQL query (and later a report) in Salesforce that generates the following data:
Count of Child records grouped by Parent records where the Parent does not have child records created in the past year.
I tried this first; however, salesforce returned an error stating 'Nesting of semi join sub-selects is not supported'.
SELECT Id, Name, Training_Course__c
FROM Training_Record__c
WHERE Training_Course__c IN (
SELECT Id
FROM Training_Course__c
WHERE Id NOT IN (
SELECT Training_Course__c
FROM Training_Record__c
WHERE CreatedDate != Last_n_Days:365
)
)
The requirements are to use a single query to obtain the data requested without forcing them to run two reports and use Excel to get the data. I'm not sure if that's possible given Salesforce's constraints.
Is this possible in SOQL? If so, what can I do differently?
This is not perfect but a decent start, you'd need to manually call count/size/length on the child records (exact method depends on your client application's language). In a SF report you can group by parent Id and call it a day. Read about "cross filters" in SF reports.
SELECT Id, Name,
(SELECT Id FROM Opportunities)
FROM Account
WHERE Id NOT IN (SELECT AccountId FROM Opportunity WHERE CloseDate = LAST_N_DAYS:365)
LIMIT 100
This will not compile:
SELECT AccountId, COUNT(Id)
FROM Opportunity
WHERE AccountId NOT IN (SELECT AccountId FROM Opportunity WHERE CloseDate = LAST_N_DAYS:365)
Error: The inner and outer selects should not be on the same object type
but if you really need something like that you could experiment, do it in 2 steps. Create helper field on account, tick the checkbox for eligible accs (with some nightly batch job maybe), then query based on that.
(normally you could do it with rollup summary field from opps to account but rollups have to be based on solid data, "deterministic". "LAST 365 DAYS", "TODAY" etc can't be used as rollup criteria)
I currently have data in a table related to transactions. Each record has a purchase ID, a Transaction Number, and up to 5 purchases assigned to the transaction. Associated with each purchase there can be up to 10 transactions. For the first transaction of each purchase I need a field that is a string of each unique purchase concatenated. My solution was slow I estimated it would take 40 days to complete. What would be the most effective way to do this?
What you are looking for can be achieved in 2 steps:
Step1: Extracting the first transaction of each purchase
Depending upon your table configuration this can be done in a couple of different ways.
If your transaction IDs are sequential, you can use something like:
select * from table a
inner join
(select purchaseid,min(transactionid) as transactionid
from table group by purchaseid) b
on a.purchaseid-b.purchaseid and a.transactionid=b.transactionid
If there is a date variable driving the transaction sequence, then:
select a.* from
(select *,row_number() over(partition by purchaseid order by date) as rownum from table)a
where a.rownum=1
Step2: Concatenating the Purchase details
This can be done by using the String_agg function if you are using the latest version of SQL server. If not, the following link highlights a couple of different ways you can do this:
Optimal way to concatenate/aggregate strings
Hope this helps.
I always feel poor when it comes to SQL. I have two tables, say table revenue which has following structure:
Revenue Table
Clicks
impressions
ad_id
device_id
money_generated
date
Another table which has devices details as follows:
Devices
device_id
device_name
One more table say Ads..
Ads Table
ad_name
ad_id
----
Now what I want is to fetch sum of impressions, clicks, money generated by a particular device for a particular ad between a particular date.
I tried this query of linking revenue & device tables but failed.
select
device_name,
revenue.impressions,
revenue.clicks,
revenue.money_generated,
revenue.ad_id
FROM
(select
device_id,
dim_ad_id,
SUM(imp_count) as impressions,
SUM(click_count) as clicks,
SUM(money_generated) as revenue,
from
revenue
GROUP BY
ad_id
GROUP BY
device_id
WHERE
dim_Date>'2017-11-02 10:33:00'
and dim_date<'2017-11-08 00:56:22') revenue
JOIN deviceTable as devices ON
devices.device_id=revenue.device_id
and devices.device_name IN ('ABC')
Please ignore the slight mistake of column names as i have renamed them before pasting it here. Please help me understanding the SQL better
You have two GROUP BY clauses in that derived table which will throw a syntax error.
select
device_name,
revenue.impressions,
revenue.clicks,
revenue.money_generated,
revenue.ad_id
FROM
(select
device_id,
dim_ad_id,
SUM(imp_count) as impressions,
SUM(click_count) as clicks,
SUM(money_generated) as revenue,
from
revenue
GROUP BY
ad_id, device_id --fixed syntax here
WHERE
dim_Date>'2017-11-02 10:33:00'
and dim_date<'2017-11-08 00:56:22') revenue
JOIN
deviceTable as devices ON
devices.device_id = revenue.device_id
and devices.device_name IN ('ABC')
LEFT JOIN
Ads on
Ads.ad_id = revenue.dim_id --or what ever it should be
I have 2 tables in a large SQL Database and i need to query across them and I am struggling TBH. Here are the parameters:
Table 1 - Live Policies
Table 2 - Email Addresses
Common Pivot = Client number which is present in both tables.
From Table 1 i need to retrieve the following fields:
Client Number
Ref Number
Name
Postcode
Inception date
Policy Type (= 'PC')
Select Client, Ptype, Ref, Incep, [Name], Postcode from [Live
Policies] where Ptype = 'PC'
This works fine.
From Table 2 i need to retrieve:
Webaddr
My question is how do i return the email address for the required records from the second table by referencing the client number? (client number is the same for all records) The second part of the statement is where i'm getting stuck.. I'm aware of the JOIN statement but if i try this i just get nowhere.. Help most appreciated!
USE a JOIN
select L.Client, L.Ptype, L.Ref, L.Incep, L.[Name], L.Postcode, E.Webaddr
from [Live Policies] as L
JOIN [Email Addresses] as E
ON L.Client = E.Client
where Ptype = 'PC'
I have two tables Patient_tbl and Consult_tbl in MS access (with the fields shown below). The first one is used to record patient info, and the second one (Consult_tbl) is used to record patient visits. They are related in a one-to-many relationship using a Patient_id field.
What I need to do is to count the visitors based on gender for a given period of time, based on the consult table using Patient_id. I don’t know how to do it. Would you please help?
Patient_tbl has the following fields:
{Patient_id
P_add
P_tel
P_gender
Other fields}
Consult_tbl has the following fields:
{Consult_id
Patient_id
C_date
C_ref
Other fields}
Join the tables on Patient_id, add a where clause for the date range and use the count() function and group by P_gender:
select p.P_gender, count(*) as "count"
from Patient_tbl p
inner join Consult_tbl c on p.Patient_id = c.Patient_id
where c.C_date >= '2015-01-10'
and c.C_date <= '2015-01-20'
group by p.P_gender