难倒在MySQL查询:如何选择具有列的值子集的行?

时间:2010-08-28 02:47:10

标签: sql mysql

有两个表,一个Contact表和一个RelationshipHistory表 联系人可以有多种类型的关系(业务,个人,志愿者等),这意味着他们可以随着时间的推移在RelationshipHistory表中有多个引用。每个关系行都有一列指示与该关系相关的事件。因此,例如,联系John Smith和ContactID 123可以在RelationshipHistory表中有两行,如:123,Individual,Fun Event和123,Volunteer,Boring Event。我需要执行的查询是“获取与事件有关系的所有联系人”Fun Event“和事件”Boring Event“。

我最初认为像这样的查询会起作用:

SELECT DISTINCT LastName, FirstName 
  FROM Contacts 
  JOIN RelationshipHistory ON RelationshipHistory.ContactKey = Contacts.ContactGUID 
 WHERE RelationshipHistory.Event = 'Fun Event' 
   AND RelationshipHistory.Event = 'Boring Event'

但它不会返回任何结果。当我第二次查看查询时,我意识到这是不可能的,因为比较发生在行上,并且列中的值同时等于两个不同的值没有意义。

查询似乎很简单,但仔细观察它,我不是如何找到列上具有两个或更多值的匹配值的行。

有没有办法使用内部选择或连接,还是我必须将结果转储到临时表中??

2 个答案:

答案 0 :(得分:1)

使用:

  SELECT LastName, FirstName 
    FROM Contacts c
    JOIN RelationshipHistory re ON re.ContactKey = c.ContactGUID 
                               AND re.Event IN ('Fun Event', 'Boring Event')
GROUP BY LastName, FirstName 
  HAVING COUNT(DISTINCT re.contactkey) = 2

您的查询不起作用,因为它希望RELATIONSHIPHISTORY.contactkey都是值,这是不可能的。这意味着您需要使用OR,或使用IN子句,该子句是同一列上多个OR的简写。但是,IN子句不支持任何模式匹配方式 - 您需要使用全文搜索(FTS)功能...

此查询的另一部分是HAVING子句 - 它计算不同的contactkey值,因为如果它们不相同,则重复“Fun Event”将是误报。

要使查询起作用,IN子句的数量必须与要计数的不同值的数量相匹配。因此,如果要查找三个或五个事件,则需要更新HAVING子句。

答案 1 :(得分:1)

如果您需要与娱乐活动和无聊活动有关系的联系人:

SELECT DISTINCT LastName, FirstName 
  FROM Contacts 
  JOIN RelationshipHistory AS BoringEvent ON Boring.ContactKey = Contacts.ContactGUID 
  JOIN RelationshipHistory AS FunEvent ON Boring.ContactKey = Contacts.ContactGUID 
 WHERE FunEvent.Event = 'Fun Event' 
   AND BoringEvent.Event = 'Boring Event'

我们正在使用同一个表进行两次连接。