首页 > 解决方案 > 是否可以在来自 3 个表的 SQL 查询中使用两个 COUNT 和两个 JOIN?

问题描述

所以我在这里想要做的是得到一份关于不同用户发送了多少电子邮件(使用类似 MailChimp 的应用程序)的报告,但我希望在一个查询中有两个不同的指标。我想知道每个用户发送了多少封单独的电子邮件。这意味着如果他们每人向 100 个联系人发送 3 封电子邮件,则显示为 300。但我还想知道发送了多少封独特的电子邮件,这意味着将显示 3。

我想得到一些看起来像:

-------------------------------------------------------------
| Full Name   | Username        | Total Sent | Unique Mails |
|-------------|-----------------|------------|--------------|
| John Doe    | jdoe@mail.com   | 12000      | 4            |
| James Smith | jsmith@mail.com | 6000       | 12           |
| Jane Jones  | jjones@mail.com | 4000       | 2            |
| ...         | ...             | ...        | ...          |
-------------------------------------------------------------

所以我可以知道 John 向很多联系人发送了几封电子邮件,而 James 向更少的联系人发送了更多电子邮件。

这是我的查询的样子。我已经更改了表名和列名,但这是对它的准确表示。

SELECT
    CONCAT(Usernames.FirstName, ' ', Usernames.LastName) AS 'Full Name',
    Usernames.Username,
    COUNT(Sent_Mail_Contacts.IDContact) AS `Total Sent`,
    COUNT(Mass_Mail.IDMass_Mail) AS `Individual E-Mails`
FROM Usernames
LEFT JOIN Sent_Mail_Contacts ON Usernames.Username = Sent_Mail_Contacts.Username
LEFT JOIN Mass_Mail ON Usernames.Username = Mass_Mail.Username
GROUP BY Usernames.Username
ORDER BY `Total Sent`

我有一个包含用户名的表,一个包含电子邮件的个人联系人的表和一个包含唯一电子邮件的表。

那么我的查询是否有意义?这甚至可能吗?因为现在当我运行它时,它给了我这样的东西:

-------------------------------------------------------------
| Full Name   | Username        | Total Sent | Unique Mails |
|-------------|-----------------|------------|--------------|
| John Doe    | jdoe@mail.com   | 12000      | 12000        |
| James Smith | jsmith@mail.com | 6000       | 6000         |
| Jane Jones  | jjones@mail.com | 4000       | 4000         |
| ...         | ...             | ...        | ...          |
-------------------------------------------------------------

我只是在两列中给了我相同的数字,并且需要 7 分钟来处理。

如果有帮助,下面是 3 个表格分别显示的示例:

Usernames
------------------------------------------------
| Username        | FirstName | LastName | ... |
|-----------------|-----------|----------|-----|
| jdoe@mail.com   | John      | Doe      | ... |
| jsmith@mail.com | James     | Smith    | ... |
| jjones@mail.com | Jane      | Jones    | ... |
| ...             | ...       | ...      | ... |
------------------------------------------------

Mass_Mail
----------------------------------------------------
| ID_Mass_Mail | Username       | Date       | ... |
|--------------|----------------|------------|-----|
|            1 | jdoe@mail.com  | 2019-01-16 | ... |
|            2 | jdoe@mail.com  | 2019-01-29 | ... |
|            3 | jjones@mail.com| 2019-02-14 | ... |
|          ... | ...            | ...        | ... |
----------------------------------------------------

Sent_Mail_Contacts
---------------------------------------------------------------------
| ID_Mass_Mail | Username       | Contact_ID | Contact_Email  | ... |
|--------------|----------------|------------|----------------|------
|            1 | jdoe@mail.com  |          1 | bob@mail.com   | ... |
|            1 | jdoe@mail.com  |          2 | jim@mail.com   | ... |
|            1 | jdoe@mail.com  |          3 | cindy@mail.com | ... |
|          ... | ...            |        ... | ...            | ... |
|            2 | jdoe@mail.com  |          4 | mike@mail.com  | ... |
|            2 | jdoe@mail.com  |          2 | jim@mail.com   | ... |
|            2 | jdoe@mail.com  |          3 | cindy@mail.com | ... |
|          ... | ...            |        ... | ...            | ... |
---------------------------------------------------------------------

标签: mysqlsqlcountleft-joinheidisql

解决方案


使用COUNT(DISTINCT ...)

SELECT
    CONCAT(Usernames.FirstName, ' ', Usernames.LastName) AS 'Full Name',
    Usernames.Username,
    COUNT(Sent_Mail_Contacts.IDContact) AS `Total Sent`,
    COUNT(DISTINCT Mass_Mail.IDMass_Mail) AS `Individual E-Mails`
FROM Usernames
LEFT JOIN Sent_Mail_Contacts ON Usernames.Username = Sent_Mail_Contacts.Username
LEFT JOIN Mass_Mail ON Usernames.Username = Mass_Mail.Username
GROUP BY Usernames.Username
ORDER BY `Total Sent`

注意:这不会使查询更快。首先,您至少应该确保在JOINs : Usernames(Username), Sent_Mail_Contacts(Username),中使用主键/外键关系Mass_Mail(Username)


推荐阅读