使用MySQL
所以我正在努力改进我写过的查询。我当前的查询有效,但我觉得我可以更有效率
基本上,我有一张表格列出了“谁与谁以及多少人谈论”。
记录如下:
电子邮件名称状态计数prod_ref (我将在帖子的末尾发布一个带有示例输出的示例集) PK =电子邮件和姓名 name是特定于运行此命令的组织的内部电子邮件地址。 (IE起诉@ innatech变成了起诉)
我最初想要的是一个查询,它将返回每个电子邮件地址的最高计数记录。
我能想到的最好的是:
SELECT email, name
FROM email_tbl AS a INNER JOIN
(SELECT email, MAX(count) cnt
FROM email_tbl
GROUP BY email) AS b ON a.email = b.email AND a.count = r.cnt
这看起来相当优化。然后,我可以通过向子查询添加HAVING子句来进一步过滤我的结果,以指定诸如SUM(count)>之类的内容。 20等。
令人讨厌的部分是状态字段。 (我知道,有一些数据重复问题会破坏正确的ER样式,但出于某些原因,我只允许使用一个表格。)
状态字段描述是否应忽略特定电子邮件。从理论上讲,电子邮件的所有记录应该具有相同的字段,但我想说明这种情况并非如此。基本上,如果存在状态为“忽略”的记录,我想丢弃该记录上的电子邮件。
我认为这样做的唯一方法是另一个子查询,通过添加到结尾
WHERE a.email NOT IN
(SELECT DISTINCT email
FROM email_tbl
WHERE status = 'ignore')
它有效...但我总是在市场上改进我的工具,所以我想知道是否有更好的方法来实现这一目标。
附录A示例集
email_tbl
bob@bob.com;phil;good;12
bob@bob.com;sue;good;5
-----------------------
rob@bob.com;phil;good;2
rob@bob.com;sue;good;2
rob@bob.com;fred;good;8
-----------------------
dan@bob.com;phil;good;5
dan@bob.com;sue;ignore;4
将返回
bob@bob.com;phil
rob@bob.com;fred
答案 0 :(得分:1)
只有几个关闭袖口查询,所以你必须测试性能:
使用NOT EXISTS代替IN应该至少比你拥有的更快,因为它一旦找到匹配就可以停止处理子查询。它是相关的,所以你必须测试。
SELECT
email,
name
FROM
Email_Tbl AS T1
INNER JOIN
(
SELECT email, MAX(count) cnt
FROM email_tbl
GROUP BY email
) AS SQ ON
SQ.email = T1.email AND
SQ.cnt = T1.count
WHERE
NOT EXISTS
(
SELECT *
FROM Email_Tbl T2
WHERE T2.email = T1.email
AND T2.status = 'Ignore'
)
SELECT
email,
name
FROM
Email_Tbl T1
LEFT OUTER JOIN Email_Tbl T2 ON
T2.email = T1.email AND
(
T2.count > T1.count OR
T2.status = 'Ignore'
)
WHERE
T2.email IS NULL
SELECT
email,
name
FROM
Email_Tbl T1
LEFT OUTER JOIN Email_Tbl T2 ON
T2.email = T1.email AND
T2.count > T1.count
LEFT OUTER JOIN Email_Tbl T3 ON
T3.email = T1.email AND
T3.status = 'Ignore'
WHERE
T2.email IS NULL OR
T3.email IS NULL