MySQL、SQL 如何检索特定列中包含较少使用值的整行

MySQL, SQL how to retrieve the full row containing less used value in a specific column

周末我有一个很好的小测验...非常抱歉,甚至很难输入标题。

上下文 让我举个例子(uuidvalue字符串):

Table1
---------------
uuid   | value
---------------
1      | x
1      | a
3      | z
2      | y
1      | x
1      | x
3      | b

这是预期的结果

---------------
uuid   | value
---------------
1      | a
3      | z
3      | b

因为以上是给定 uuid 所用平均值中不太常见的值(或相等值)的行。 我正在玩 GROUP BYDISTINCTCOUNT...

尝试一次

SELECT uuid, COUNT(uuid) as time_used, value
FROM table1
GROUP BY uuid, value ORDER BY COUNT(*) DESC;

尝试两次

SELECT uuid, COUNT(uuid) as occ
FROM (
    SELECT uuid, COUNT(uuid) as occ, value
    FROM table1
    GROUP BY uuid, value ORDER BY COUNT(*)) as t
GROUP BY uuid;

尝试三次

SELECT uuid as occ
FROM (
    SELECT uuid, COUNT(uuid) as occ, value
    FROM table1
    GROUP BY uuid, value ORDER BY COUNT(*)) as t
GROUP BY uuid
HAVING COUNT(uuid) > 1;

但是不对,还漏了一步...

http://sqlfiddle.com/#!9/593a74/3

注意我正在使用 MySQL,数据很少(2000 年左右),但仍希望成为 'performant',它们会增长,我希望符合 only_full_group_by 声明MySQL。 谢谢。

在 MySQL 8+ 中,您将使用 window 函数:

SELECT uv.*
FROM (SELECT uuid, COUNT(*) as cnt, value,
             RANK() OVER (PARTITION BY uuid ORDER BY COUNT(*)) as seqnum
      FROM table1
      GROUP BY uuid, value 
     ) uv
WHERE seqnum = 1;

在MySQL 8之前的版本中,你可以通过子查询得到每个uuid/value组合的计数来生成你需要的结果,然后使用获取每个 uuid 的最小计数值和总计数值,然后将该结果连接到子查询的另一个副本以获取输出:

SELECT c.uuid, c.value
FROM (
  SELECT uuid, MIN(cnt) AS min_cnt
  FROM (
    SELECT uuid, value, COUNT(*) AS cnt
    FROM table1
    GROUP BY uuid, value
  ) c
  GROUP BY uuid
  HAVING SUM(cnt) > 1
) m
JOIN (
  SELECT uuid, value, COUNT(*) AS cnt
  FROM table1
  GROUP BY uuid, value
) c ON c.uuid = m.uuid AND c.cnt = m.min_cnt

输出:

uuid    value
1       a
3       z
3       b

Demo on dbfiddle