首页 > 解决方案 > SQL 根据列值频率获取行

问题描述

假设我有一个如下所示的表:

厨师名 chef_cuisine
马里奥 意大利语
杰克 美国人
马里奥 意大利语
马里奥 美国人
杰克 希腊语
杰克 希腊语

假设每一行代表每个厨师做的一顿饭。但是我们想从这张表中知道,这些人是什么类型的厨师?

我们希望为每位厨师找到最常用的chef_cuisine值。

您将如何使用 SQL 找到它,结果将显示为:

厨师名 chef_cuisine
马里奥 意大利语
杰克 希腊语

标签: sql

解决方案


如果您刚刚开始使用 SQL,那么在您直接进入答案之前,了解该过程非常重要

您需要首先将您的需求分解为更小的部分,每个部分都可以轻松解决

频率可以使用该函数来识别,因此首先通过按和分组来COUNT()聚合您的记录集:chef_namechef_cuisine

SELECT chef_name, chef_cuisine, cuisine_count = count(1)
FROM the_table
GROUP BY chef_name, chef_cuisine
ORDER BY cuisine_count DESC
厨师名 chef_cuisine 美食计数
杰克 希腊语 2
马里奥 意大利语 2
杰克 美国人 1
马里奥 美国人 1

你可以看到这已经接近你要找的了,这个结果集可以帮助你可视化结果,我们只需要chef_cuisine为每个选择具有最高计数的那个chef_name

一种方法是在按降序()TOP 1排序后选择第一行( ) ,第一个原则方法是使用内联子查询:DESC

SELECT chef_name , (
    SELECT TOP 1 chef_cuisine
    FROM the_table lkp
    WHERE lkp.chef_name = t.chef_name
    GROUP BY lkp.chef_cuisine
    ORDER BY COUNT(1) DESC
   ) chef_cuisine
FROM the_table t
厨师名 chef_cuisine
马里奥 意大利语
杰克 希腊语
马里奥 意大利语
马里奥 意大利语
杰克 希腊语
杰克 希腊语

要从此结果中获取唯一行,您可以使用GROUP BY或者您可以简单地使用我们DISTINCT

SELECT DSTINCT chef_name , (
    SELECT TOP 1 chef_cuisine
    FROM the_table lkp
    WHERE lkp.chef_name = t.chef_name
    GROUP BY lkp.chef_cuisine
    ORDER BY COUNT(1) DESC
   ) chef_cuisine
FROM the_table t
厨师名 chef_cuisine
杰克 希腊语
马里奥 意大利语

这些类型的查询非常常见,因此大多数数据库引擎都包含对窗口查询的支持,这实际上是在同一结果表的子集上执行简单聚合(如计数行编号)的简便方法,而无需编写嵌套查询或连接到自身的表。

窗口查询最有用的方面可能是它们不需要您更改原始结果集,您可以返回原始查询中的所有行,并将窗口查询的结果附加为附加列。

a_horse_with_no_name 的响应是一个很好的例子,说明如何使用DENSE_RANK()窗口函数运行以获得相同的结果


推荐阅读