Mysql SQL:选择最多出现两次

Mysql SQL:选择最多出现两次,mysql,sql,select,Mysql,Sql,Select,我在sql中遇到了一个小问题,我无法找到一种方法来构建正确的语句。当etud和mod的出现次数相等时,我只需要在结果中包含具有最大SES的行: etud|sess|mod|eta 1------1---M1--nv 1------2---M1--v 2------1---M1--nv 3------1---M1--v 4------1---M1--v 现在我需要的结果是: etud|sess|mod|eta 1------2---M1--v 2------1---M1--nv 3------1

我在sql中遇到了一个小问题,我无法找到一种方法来构建正确的语句。当etud和mod的出现次数相等时,我只需要在结果中包含具有最大SES的行:

etud|sess|mod|eta
1------1---M1--nv
1------2---M1--v
2------1---M1--nv
3------1---M1--v
4------1---M1--v
现在我需要的结果是:

etud|sess|mod|eta
1------2---M1--v
2------1---M1--nv
3------1---M1--v
4------1---M1--v
提前感谢。

这实际上只是一个由etud和mod组成的分组:

编辑任务后更新: 虽然MySQL允许您只将列添加到上面的查询中,而不将其添加到GROUP BY中,但该列的值是不确定的,如果您有多个可能的值,则无法计划返回哪一个,通常它将是第一个

要拉入与maxses匹配的剩余eta列,可以对子查询进行连接

SELECT
  main.etud,
  maxsess.maxsess AS sess
  main.mod,
  main.eta
FROM
  yourtable
  JOIN (
    SELECT
      etud,
      MAX(sess) AS maxsess,
      mod
    FROM yourtable
    GROUP BY etud, mod
    /* JOIN all 3 columns of the subquery which gets the MAX() against the rest of the table */
  ) maxsess ON main.etud = maxsess.etud AND main.sess = maxsess.maxsess AND main.mod = maxsess.mod
SQL FIDLE

您可以使用。我假设您只需要每个etud mod paring的最大sess,您可以通过此查询检索:

SELECT etud, max(sess) as sess, mod FROM table GROUP BY etud, mod;
但如果您只想删除最小SES,并获取其他行,那么这是一个解决方案:

SELECT etud, sess, mod
FROM table 
JOIN (SELECT etud, min(sess) as sess, mod FROM table GROUP BY etud, mod) AS mintable
  ON table.etud = mintable.etud 
    AND table.mod = mintable.mod
    AND table.sess <> mintable.sess
第一个查询将返回

etud|sess|mod
1------3------M1
2------2------M1
etud|sess|mod
1------2------M1
1------3------M1
2------2------M1
第二个查询将返回

etud|sess|mod
1------3------M1
2------2------M1
etud|sess|mod
1------2------M1
1------3------M1
2------2------M1

以下是SQL表和插入: 创建表esm etud INT11、sess INT11、modval char3

INSERT INTO esm (etud,sess,modval) VALUES ( 1,1,'M1');
INSERT INTO esm (etud,sess,modval) VALUES ( 1,2,'M1');
INSERT INTO esm (etud,sess,modval) VALUES ( 2,1,'M1');
INSERT INTO esm (etud,sess,modval) VALUES ( 3,1,'M1');
INSERT INTO esm (etud,sess,modval) VALUES ( 4,1,'M1');
以及查询:

SELECT esm1.* FROM esm esm1
INNER JOIN (SELECT MIN(etud) as minetud, sess, modval
FROM  esm
GROUP BY   sess, modval) esm2
ON esm1.sess=esm2.sess AND esm1.modval=esm2.modval
WHERE esm1.etud <> minetud;

etud和mod怎么可能相等?@Lion我认为这意味着消除etud和mod.Lion每组的最小成功率。我相信你误解了。op意味着,如果结果集有多行共享etud和mod作为一个值,则只包含sess值最高的行。tnx很多,正如您看到的,我仍然是SQL初学者,您建议我如何达到良好的技能水平@TheEighthEro在这里写了很多查询,读了很多关于堆栈溢出的标记为[sql]的问题。@TheEighthEro当您准备好学习sql连接时,由堆栈溢出的创建者之一Jeff Atwood阅读您刚才给出的解决方案不适用于已编辑的问题,请查看编辑。返回错误的1-2-M1-nv,必须为1-2-M1-v;或者?@TheEighthEro,这是因为MySQL对您在输出中包含的列非常宽容,而这些列没有出现在GroupBy中。其他RDBMS不允许您尝试的操作。请参见上面的“我的编辑”,通过对子查询进行连接来拉入其他列。
SELECT esm1.* FROM esm esm1
INNER JOIN (SELECT MIN(etud) as minetud, sess, modval
FROM  esm
GROUP BY   sess, modval) esm2
ON esm1.sess=esm2.sess AND esm1.modval=esm2.modval
WHERE esm1.etud <> minetud;
+------+------+--------+
| etud | sess | modval |
+------+------+--------+
|    2 |    1 | M1     | 
|    3 |    1 | M1     | 
|    4 |    1 | M1     | 
+------+------+--------+