MySQL - 在单列上选择distinct

时间:2012-08-14 18:50:01

标签: mysql join inner-join

我的查询效果很好。我与Freetrials和Contacts有N:N关系,与Freetrials和Companies有N:1的关系。 Freetrial可以有多个联系人,联系人可以注册多个Freetrial。一个Freetrial只能有一家公司,公司可以注册多个Freetrials。

SELECT `freetrial`.*,`company`.name as name, `contact`.first_name,`contact`.last_name FROM `contact_freetrial`
    INNER JOIN `freetrial` ON `contact_freetrial`.freetrial_id=`freetrial`.id
    INNER JOIN `contact` ON `contact_freetrial`.contact_id=`contact`.id
    LEFT JOIN `company` ON `company`.id=`freetrial`.company_id

这很有效,直到我有2个联系人:

Id  Company    Contact          Date     
110 MCC        P Sh***      08/14/2012
110 MCC        W Bu***      08/14/2012
111 Foo        x yy***      08/14/2012
112 BAR        y zz***      08/14/2012

如果有多个联系人,我想只显示一个SINGLE公司/ freetrial。所以我基本上只想让它看起来像这样:

Id  Company    Contact          Date     
110 MCC        P Sh***      08/14/2012
111 Foo        x yy***      08/14/2012
112 BAR        y zz***      08/14/2012

任何帮助它做到这一点将不胜感激。

3 个答案:

答案 0 :(得分:2)

这个想法是你希望得到随机联系。然后加入联系信息:

select t.*, c.first_name, c.last_name
from (SELECT `freetrial`.*,`company`.name as name,
             (select ContactId
              from Contact where contact.company_id = company.id
              order by rand()
              limit 1
             ) as thecontactid
      FROM  `contact_freetrial` INNER JOIN
             freetrial`
             ON `contact_freetrial`.freetrial_id=`freetrial`.id LEFT JOIN
            `company` ON `company`.id=`freetrial`.company_id
    ) t join
    contact c
    on t.thecontactid = c.contactid

这使用相关子查询选择随机联系。然后它加入了信息。

使用“group by”方法的问题是mysql不保证不同的字段来自同一记录。您可以从一个记录中获取第一个名称,从另一个记录中获取姓氏。因此,即使它似乎工作,也不能保证工作。 (除此之外,它使用的语法是非标准的分组。)

答案 1 :(得分:1)

您可以使用GROUP BY(例如GROUP BY freetrial.id, company.name)将所有结果按照自由/公司组合分组 - 从而每个自由/公司只返回一行:

SELECT
    `freetrial`.*,`company`.name as name, `contact`.first_name,`contact`.last_name
FROM
    `contact_freetrial`
    INNER JOIN `freetrial` ON `contact_freetrial`.freetrial_id=`freetrial`.id
    INNER JOIN `contact` ON `contact_freetrial`.contact_id=`contact`.id
    LEFT JOIN `company` ON `company`.id=`freetrial`.company_id
GROUP BY
    freetrial.id, company.name

作为额外奖励,您可以使用GROUP_CONCAT()获取给定自由/公司的每个联系人列表 - 所有这些都在同一行:

SELECT
    `freetrial`.*,`company`.name as name,
    GROUP_CONCAT(CONCAT(contact.first_name, ' ', contact.last_name)) AS contacts
FROM
    `contact_freetrial`
    INNER JOIN `freetrial` ON `contact_freetrial`.freetrial_id=`freetrial`.id
    INNER JOIN `contact` ON `contact_freetrial`.contact_id=`contact`.id
    LEFT JOIN `company` ON `company`.id=`freetrial`.company_id
GROUP BY
    freetrial.id, company.name

在这个例子中,我还使用CONCAT()来组合联系人的名字和姓氏。它将返回的列表将是每个联系人的逗号分隔列表 - 如果有多个 - 为每个免费/公司组合。

答案 2 :(得分:0)

这将按最新联系方式为您提供行。

SELECT `freetrial`.*,`company`.name as name, `contact`.first_name,
                   `contact`.last_name FROM `contact_freetrial` A
    INNER JOIN `freetrial` ON `contact_freetrial`.freetrial_id=`freetrial`.id
    INNER JOIN `contact` ON `A`.contact_id=`contact`.id
    LEFT JOIN `company` ON `company`.id=`freetrial`.company_id
where A.id = (select max(id) from contact_freetrial where contact_id = A.id)