子查询中的字段,基于行的年龄而不是“分组依据”

时间:2013-05-15 11:07:59

标签: mysql

我似乎无法正确查询此查询。我有这样的表(简化):

person: PersonID, ...other stuff...
contact: ContactID, PersonID, ContactDate, ContactTypeID, Description

我想获得所有具有某种类型(或类型)的联系人但没有其他类型的联系人的列表。一个易于理解的例子:在没有发送感谢卡之后检查收到的礼品记录。可能还有其他先前发送的感谢卡(与其他礼品有关),但如果最近发生的礼品收到(我们说的是ContactTypeID = 12)后面没有发送谢谢(ContactTypeID = 11) ),PersonID应该在结果集中。另一个例子:邮件列表将由选择(12)但未最近选择退出(11)的所有人组成。

我的查询尝试是:

SELECT person.PersonID FROM person
INNER JOIN (SELECT PersonID,ContactTypeID,MAX(ContactDate) FROM contact
  WHERE ContactTypeID IN (12,11) GROUP BY PersonID) AS seq
  ON person.PersonID=seq.PersonID
WHERE seq.ContactTypeID IN (12)`

似乎子查询中返回的ContactTypeID是针对表中输入的最后一条记录,无论哪条记录具有最大日期。但我无法弄清楚如何解决它。很抱歉,如果之前已经询问过(几乎所有内容都有!),但我不知道要搜索的条件。

1 个答案:

答案 0 :(得分:1)

哇。一个系统来检查谁是好人并发送了感谢信。我想我会在你的名单中......

反正。放手一搏。我们的想法是创建两个视图:第一个包含personId,第一个包含最近收到的礼物,第二个包含personId和最近发送的感谢。使用left outer join将他们加入到一起,以确保包含从未发送过感谢信的人,然后在最近收到的时间和最近的感谢时间之间进行比较,以找到不礼貌的人:

select g.personId,
g.mostRecentGiftReceivedTime,
t.mostRecentThankYouTime
from
(
select p.personId,
max(ContactDate) as mostRecentGiftReceivedTime
from person p inner join contact c on p.personId = c.personId
where c.ContactTypeId = 12
group by p.personId
) g
left outer join
(
select p.personId,
max(ContactDate) as mostRecentThankYouTime
from person p inner join contact c on p.personId = c.personId
where c.ContactTypeId = 11
group by p.personId
) t on g.personId = t.personId
where t.mostRecentThankYouTime is null
or t.mostRecentThankYouTime < g.mostRecentGiftReceivedTime;

以下是我使用的测试数据:

create table person (PersonID int unsigned not null primary key);

create table contact (
ContactID int unsigned not null primary key,
PersonID int unsigned not null,
ContactDate datetime not null,
ContactTypeId int unsigned not null,
Description varchar(50) default null
);

insert into person values (1);
insert into person values  (2);
insert into person values  (3);
insert into person values  (4);

insert into contact values  (1,1,'2013-05-01',12,'Person 1 Got a present');
insert into contact values  (2,1,'2013-05-03',11,'Person 1 said "Thanks"');
insert into contact values  (3,1,'2013-05-05',12,'Person 1 got another present. Lucky person 1.');

insert into contact values  (4,2,'2013-05-01',11,'Person 2 said "Thanks". Not sure what for.');
insert into contact values  (5,2,'2013-05-08',12,'Person 2 got a present.');

insert into contact values  (6,3,'2013-04-25',12,'Person 3 Got a present');
insert into contact values  (7,3,'2013-04-30',11,'Person 3 said "Thanks"');
insert into contact values  (8,3,'2013-05-02',12,'Person 3 got another present. Lucky person 3.');
insert into contact values  (9,3,'2013-05-05',11,'Person 3 said "Thanks" again.');

insert into contact values  (10,4,'2013-04-30',12,'Person 4 got his first present');