计算行并从多个表中获取最新的日期

时间:2015-04-06 02:01:05

标签: sql sql-server join count

我有2个表,Customer和CustomerActivity,如下图所示:

enter image description here

我想输出一个表:

  • 包含来自Customer表的所有列,其中CustomerType ='Existing Customer',另外还有2列:
  • totalActivity(count activityID) - 显示每个客户的总活动数。
  • latestActivity(max checkinTime) - 显示最近的活动日期时间

到目前为止,我有这两个查询,但我不知道如何组合/加入和过滤它们以获得我需要的东西。任何人都可以帮助1个查询(并且一些解释将是完美的)

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

4 个答案:

答案 0 :(得分:2)

你真的很亲密。以下是您的查询应该是什么样的:

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'

子查询(在INNER JOIN内)使用COUNT(*)检索活动总数,并使用每个客户的MAX(checkinTime)检索最新活动。之后,您可以将其加入Customer上的customerId表格。然后,您只需添加WHERE子句即可过滤'Existing Customer'

答案 1 :(得分:1)

我还没有针对实际模式对其进行测试,但是这样的事情应该有效(即使他们没有活动,这种方法也会向客户显示,如果您只想要客户,则只需将左连接更改为内连接活性):

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

答案 2 :(得分:1)

通过使用group by和窗口替换,您可以在不row_number()的情况下获得所需内容:

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';

此版本可让您从最近的活动行中获得您喜欢的任何列。

编辑:

在你原来的问题中,我认为你想要最新的活动。如果您只想要最新的日期时间,那么聚合就可以了:

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';

答案 3 :(得分:0)

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'

如果您详细说明没有活动的客户,可以将查询更改为使用左连接