哪两个数字最常同时出现?

Which two numbers are most frequently found together?

我有一个 mysql table 记录用户 ID,具体取决于他们选择的图片(pic1、pic2 或 pic3)。我希望能够打印出在 同一行 中最常找到的两个用户 ID,而不管他们选择了哪张图片。

在下面的 table 中,答案是 4 和 6,因为它们最常见于同一行。我不知道如何构建一个查询来执行此操作,我认为唯一的方法可能是使用多查询,但我想出了如何构建它们。谁能帮帮我?

     pic1    |    pic2   |   pic3   
-------------------------------------
       4            null       6
       6             4        null
       4             9        null
       6            null       4

我想我的查询的第一部分看起来像这样,但接下来呢?:注意 $userid 是登录用户。

"SELECT pic1, pic2, pic3 FROM mytable where pic1='$userid' OR pic2='$userid' OR pic3='$userid'";

如果每一行只有两个不同的用户,您可以使用此查询来获取所有有序的用户对以及他们一起出现的次数:

SELECT mn, mx, COUNT(*)
  FROM (select if(pic1 is null, least(pic2, pic3), least(pic1, coalesce(pic2, pic3))) mn,
               if(pic1 is null, greatest(pic2, pic3), greatest(pic1, coalesce(pic2, pic3))) mx
          from t) x
 GROUP BY mn, mx
 ORDER BY count(*) DESC;

请注意,最小和最大函数 return 如果值为 NULL,则为 NULL,这就是为什么需要 if 和合并函数。

要仅获取具有最大计数的用户对,查询将更长:

SELECT mn, mx, count(*) cnt
  FROM (select if(pic1 is null, least(pic2, pic3), least(pic1, coalesce(pic2, pic3))) mn,
               if(pic1 is null, greatest(pic2, pic3), greatest(pic1, coalesce(pic2, pic3))) mx
          from t) x
 GROUP BY mn, mx
HAVING count(*) = (select max(cnt) from (SELECT mn, mx, count(*) cnt
                                           FROM (select if(pic1 is null, least(pic2, pic3), least(pic1, coalesce(pic2, pic3))) mn,
   if(pic1 is null, greatest(pic2, pic3), greatest(pic1, coalesce(pic2, pic3))) mx
                     from t) x
                                          GROUP BY mn, mx) y);

fiddle

这应该会给您正确的结果:

SELECT LEAST(p1, p2) AS p1, GREATEST(p1,p2) AS p2
FROM (
  SELECT pic1 AS p1, pic2 AS p2
  FROM mytable WHERE pic1 IS NOT NULL AND pic2 IS NOT NULL
  UNION ALL
  SELECT pic1 AS p1, pic3 AS p2
  FROM mytable WHERE pic1 IS NOT NULL AND pic3 IS NOT NULL
  UNION ALL
  SELECT pic2 AS p1, pic3 AS p2
  FROM mytable WHERE pic3 IS NOT NULL AND pic2 IS NOT NULL
) s
GROUP BY LEAST(p1, p2), GREATEST(p1,p2)
ORDER BY COUNT(*) DESC
LIMIT 1