Reputation: 13824
I have 2 tables, Customer and CustomerActivity as showed in the picture below:
I want to output a table that:
So far I have these 2 queries but I don't know how to combine/join and filter them to get what I need. Anyone can help with 1 query (and some explanation would be perfect)
SELECT customerId, firstName, birthDate, customerType
FROM Customer
WHERE Customer.customerType = 'Existing Customer'
SELECT t1.activityId, t1.checkinTime, t1.customerId
FROM CustomerActivity t1
inner join (
SELECT customerId, max(checkinTime) as Lastest
FROM CustomerActivity
group by customerId
) t2 on t1.customerId = t2.customerId and t1.checkinTime = t2.Lastest
Upvotes: 1
Views: 94
Reputation: 179
Select c.customerId, c.firstName, c.lastName, c.birthDate, c.customerType, gca.latestCheckIn, gca.count
from customer as c,
(select ca.customerId, max(ca.checkInTime) as latestCheckIn, count(*) as checkinCount
from customerActivity as ca
group by ca.customerId) as gca
where gca.customerId = c.customerId AND c.customerType = 'Existing Customer'
If you clarify more about customer with no activity, one can change the query to using left join
Upvotes: 0
Reputation: 1270573
You can get what you want without group by
, by using row_number()
and window fu instead:
SELECT c.*, ca.numActivities, ca.activityId as LastActivity
FROM Customer c JOIN
(select ca.*,
count(*) over (partition by ca.CustomerId) as numActivities
row_number() over (partition by ca.CustomerId order by checkinTime desc) as seqnum
from CustomerActivity ca
) ca
on c.customerId = ca.customerId and ca.seqnum = 1
WHERE c.customerType = 'Existing Customer';
This version will let you get whatever columns you like from the most recent activity row.
EDIT:
In your original question, I thought you wanted the latest activity. If you just want the latest datetime, then aggregation works:
SELECT c.*, ca.numActivities, ca.lastActivityDateTime
FROM Customer c JOIN
(select ca.*,
count(*) as numActivities
max(checkinTime) as lastActivityDateTime
from CustomerActivity ca
) ca
on c.customerId = ca.customerId
WHERE c.customerType = 'Existing Customer';
Upvotes: 1
Reputation: 417
I haven't tested it against an actual schema, but something like this should work (this approach will show customers even if they have no activity, simply change the left join to an inner join if you only want customers with activity):
SELECT c.CustomerID
, c.FirstName
, c.BirthDate
, c.CustomerType
, COUNT(ca.ActivityID) AS TotalActivity
, MAX(ca.CheckinTime) AS MostRecentActivity
FROM Customer c
LEFT JOIN CustomerActivity ca ON c.CustomerID = ca.CustomerID
WHERE c.CustomerType = 'Existing Customer'
GROUP BY c.CustomerID
, c.FirstName
, c.BirthDate
, c.CustomerType
Upvotes: 1
Reputation: 31879
You're actually close. Here is what your query should look like:
SELECT
c.customerId,
c.firstName,
c.lastName,
c.birthDate,
c.customerType,
ca.totalActivity,
ca.latestActivity
FROM Customer c
INNER JOIN(
SELECT
customerId,
latestActivity = MAX(checkinTime),
totalActivity = COUNT(*)
FROM CustomerActivity
GROUP BY customerId
) ca
ON ca.customerId = c.customerId
WHERE
c.customerType = 'Existing Customer'
The subquery (inside the INNER JOIN
) retrieves the total number of activities by using COUNT(*)
and latest activity using MAX(checkinTime)
of each customer. After that, you would want to join it to the Customer
table on customerId
. You then add a WHERE
clause to filter for 'Existing Customer'
only.
Upvotes: 2