在SQL中选择最常见的项目

时间:2012-02-18 15:03:53

标签: mysql sql apache

我有一个mysql数据库,我想选择“name”和“postcode”上相同的所有值。查询需要选择其他字段中最常见的数据。

如果我有:

name postcode test  test2
a    a        1     2
a    a        1     2
a    a        2     1
a    a        1     1
a    a        1     1

然后这需要返回

a    a        1     1

因为(测试)1在表中是4次,而(test2)1是3次。所以我需要列中最常见的数据,其中名称和邮政编码是相同的。

2 个答案:

答案 0 :(得分:1)

这是我的第一个方法:

select distinct
    name, 
    postcode, 
    (select 
       s.test
    from 
       your_table s
    where
       name s.name = m.name, s.postcode = m.postcode
    group by 
       s.name, s.postcode, s.test
    order by count(*) desc
    limit 1 ) as test,
    (select 
       s.test2
    from 
       your_table s
    where
       name s.name = m.name, s.postcode = m.postcode
    group by 
       s.name, s.postcode, s.test2
    order by  count(*) desc
    limit 1 ) as test2
from your_table m

如果您不需要高性能,这是一个解决方案。如果经常执行此查询,那么您应该寻找另一种方法。

<强> EDITED

如果您需要更高的性能并且还需要不同的行,则可以删除distinct并在查询末尾添加group by name, postcode子句。 查询看起来像:

select ... group by name, postcode

这不是标准SQL,但是mysql允许这样做以获得更好的性能:

Quoting MySQL doc

  

在标准SQL中,包含GROUP BY子句的查询无法引用   选择列表中未分配的非聚合列   GROUP BY子句。 MySQL扩展了GROUP BY的使用以便选择   list可以引用GROUP BY中未命名的非聚合列   条款。这意味着前面的查询在MySQL中是合法的。您可以   使用此功能可以避免不必要的操作来获得更好的性   列排序和分组。

答案 1 :(得分:1)

当你写“我需要最常见的数据”时,我解释这意味着你正在寻找模式平均值,它只是指定分组列中最常出现的数字。这可以通过分组然后按计数降序排序并选择第一个结果来实现。

如,

SELECT t.name
       ,t.postcode
       ,modevaluefortest = 
           (SELECT t2.test
              FROM [table] t2
             WHERE t.name = t2.name AND t.postcode = t2.postcode
             GROUP BY name, postcode, test
             ORDER BY COUNT(*) DESC
             LIMIT 1
             )
       ,modevaluefortest2 = 
           (SELECT t2.test2
              FROM [table] t2
             WHERE t.name = t2.name AND t.postcode = t2.postcode
             GROUP BY name, postcode, test2
             ORDER BY COUNT(*) DESC
             LIMIT 1
             )
  FROM [table] t
 WHERE t.name = t.postcode -- all values that are equal on "name" and "postcode"
 GROUP BY t.name, t.postcode