繁体   English   中英

选择按汇总最大的列分组的行

[英]Select rows grouped by a column having max aggregate

给定以下数据集,我如何找到作为大多数具有“已接受”决策的ApplicationID的引用的电子邮件地址?

CREATE TABLE IF NOT EXISTS `EmailReferences` (
  `ApplicationID` INT NOT NULL,
  `Email` VARCHAR(45) NOT NULL,
  PRIMARY KEY (`ApplicationID`, `Email`)
);
INSERT INTO EmailReferences (ApplicationID, Email)
VALUES
(1, 'ref10@test.org'), (1, 'ref11@test.org'), (1, 'ref12@test.org'),
(2, 'ref20@test.org'), (2, 'ref21@test.org'), (2, 'ref22@test.org'),
(3, 'ref11@test.org'), (3, 'ref31@test.org'), (3, 'ref32@test.org'),
(4, 'ref40@test.org'), (4, 'ref41@test.org'), (4, 'ref42@test.org'),
(5, 'ref50@test.org'), (5, 'ref51@test.org'), (5, 'ref52@test.org'),
(6, 'ref60@test.org'), (6, 'ref11@test.org'), (6, 'ref62@test.org'),
(7, 'ref70@test.org'), (7, 'ref71@test.org'), (7, 'ref72@test.org'),
(8, 'ref10@test.org'), (8, 'ref81@test.org'), (8, 'ref82@test.org')
;

CREATE TABLE IF NOT EXISTS `FinalDecision` (
  `ApplicationID` INT NOT NULL,
  `Decision` ENUM('Accepted', 'Denied') NOT NULL,
  PRIMARY KEY (`ApplicationID`)
);
INSERT INTO FinalDecision (ApplicationID, Decision)
VALUES
(1, 'Accepted'), (2, 'Denied'),
(3, 'Accepted'), (4, 'Denied'),
(5, 'Denied'),   (6, 'Denied'),
(7, 'Denied'),   (8, 'Accepted')
;

相同的小提琴: http ://sqlfiddle.com/#!9/03bcf2/1

最初,我使用LIMIT 1ORDER BY CountDecision DESC ,如下所示:

SELECT  er.email, COUNT(fd.Decision) AS CountDecision
FROM    EmailReferences AS er
JOIN    FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID
WHERE   fd.Decision = 'Accepted'
GROUP   BY er.email
ORDER   BY CountDecision DESC
LIMIT   1
;

但是,我想到我可以有多个电子邮件地址引用不同的“最受接受”决策(例如,可以说是平局),并且可以使用LIMIT关键字将其过滤掉(是正确的措词吗?)。 。

然后,我尝试对上述查询进行变体,将ORDER BYLIMIT行替换为:

HAVING MAX(CountDecision)

但是我意识到那只是陈述的一半:需要将MAX(CountDecision)与某种事物进行比较。 我就是不知道

任何指针将不胜感激。 谢谢!

注意:这是用于家庭作业。

更新:明确地说,我正在尝试从EmailReferences查找Email的值和计数。 但是,我只希望具有FinalDecision.Decision = 'Accepted' (在匹配的ApplicantID )。 根据我的数据,结果为:

Email          | CountDecision
---------------+--------------
ref10@test.org | 2
ref11@test.org | 2

基本上,您需要做两件事...首先,您需要找到什么是maxCount,然后找到具有最大计数的记录。

现在,您可以将这两个步骤合并到一个嵌套查询中,或者将结果存储在变量中,然后在第二个查询中使用它。 我个人试图避免内部查询,因为它们会导致性能问题并且读取起来更复杂,因此我在这里使用变量选项:

-- Find out what max count is and store it in a variable
SELECT  @maxcount := COUNT(fd.Decision) AS CountDecision
FROM    EmailReferences AS er
JOIN    FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID
WHERE   fd.Decision = 'Accepted'
GROUP   BY er.email
ORDER BY CountDecision desc
Limit 1;

-- get emails with @maxcount
SELECT  er.Email, COUNT(fd.Decision) AS CountDecision
FROM    EmailReferences AS er
JOIN    FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID
WHERE   fd.Decision = 'Accepted'
GROUP   BY er.email
HAVING  COUNT(fd.Decision) = @maxcount;

MySQL仍然缺少窗口功能,但是当版本8可以投入生产时,这将变得更加容易。 因此,对于将来的参考,或者对于那些已经具有窗口功能的数据库(例如Mariadb):

 CREATE TABLE IF NOT EXISTS `EmailReferences` ( `ApplicationID` INT NOT NULL, `Email` VARCHAR(45) NOT NULL, PRIMARY KEY (`ApplicationID`, `Email`) ); 

 INSERT INTO EmailReferences (ApplicationID, Email) VALUES (1, 'ref10@test.org'), (1, 'ref11@test.org'), (1, 'ref12@test.org'), (2, 'ref20@test.org'), (2, 'ref21@test.org'), (2, 'ref22@test.org'), (3, 'ref30@test.org'), (3, 'ref31@test.org'), (3, 'ref32@test.org'), (4, 'ref40@test.org'), (4, 'ref41@test.org'), (4, 'ref42@test.org'), (5, 'ref50@test.org'), (5, 'ref51@test.org'), (5, 'ref52@test.org'), (6, 'ref60@test.org'), (6, 'ref11@test.org'), (6, 'ref62@test.org'), (7, 'ref70@test.org'), (7, 'ref71@test.org'), (7, 'ref72@test.org'), (8, 'ref10@test.org'), (8, 'ref81@test.org'), (8, 'ref82@test.org') ; 

 CREATE TABLE IF NOT EXISTS `FinalDecision` ( `ApplicationID` INT NOT NULL, `Decision` ENUM('Accepted', 'Denied') NOT NULL, PRIMARY KEY (`ApplicationID`) ); 

 INSERT INTO FinalDecision (ApplicationID, Decision) VALUES (1, 'Accepted'), (2, 'Denied'), (3, 'Accepted'), (4, 'Denied'), (5, 'Denied'), (6, 'Denied'), (7, 'Denied'), (8, 'Accepted') ; 

 select email, CountDecision from ( SELECT er.email, COUNT(fd.Decision) AS CountDecision , max(COUNT(fd.Decision)) over() maxCountDecision FROM EmailReferences AS er JOIN FinalDecision AS fd ON er.ApplicationID = fd.ApplicationID WHERE fd.Decision = 'Accepted' GROUP BY er.email ) d where CountDecision = maxCountDecision 
\n 电邮|  计数决定\n :------------- |  ------------:\n ref10@test.org |  2\n

dbfiddle 在这里

例如...

SELECT a.*
  FROM 
     ( SELECT x.email
            , COUNT(*) total
         FROM emailreferences x
         JOIN finaldecision y
           ON y.applicationid = x.applicationid
        WHERE y.decision = 'accepted'
        GROUP
           BY x.email
     ) a
  JOIN
     ( SELECT COUNT(*) total
         FROM emailreferences x
         JOIN finaldecision y
           ON y.applicationid = x.applicationid
        WHERE y.decision = 'accepted'
        GROUP
           BY x.email
        ORDER 
           BY total DESC 
        LIMIT 1
     ) b
    ON b.total = a.total;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM