Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
获取SQL中另一列的每个值的最常用值_Sql_Postgresql_Greatest N Per Group - Fatal编程技术网

获取SQL中另一列的每个值的最常用值

获取SQL中另一列的每个值的最常用值,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我有一张这样的桌子: Column | Type | Modifiers ---------+------+----------- country | text | food_id | int | eaten | date | 对于每个国家,我都想得到最常吃的食物。我能想到的最好办法(我正在使用postgres)是: 在最后一个语句中,需要GROUP BY和max()来打破两种不同食物计数相同的关系 对于概念上简单的东西来说,这似乎需要做很多工作。有更直接的方法吗?试试

我有一张这样的桌子:

 Column  | Type | Modifiers 
---------+------+-----------
 country | text | 
 food_id | int  | 
 eaten   | date | 
对于每个国家,我都想得到最常吃的食物。我能想到的最好办法(我正在使用postgres)是:

在最后一个语句中,需要GROUP BY和max()来打破两种不同食物计数相同的关系


对于概念上简单的东西来说,这似乎需要做很多工作。有更直接的方法吗?

试试这样的方法

select country, food_id, count(*) cnt 
into #tempTbl 
from mytable 
group by country, food_id

select country, food_id
from  #tempTbl as x
where cnt = 
  (select max(cnt) 
  from mytable 
  where country=x.country 
  and food_id=x.food_id)
这可以放在一个单一的选择,但我现在没有时间去胡闹


祝你好运。

以下是在没有临时表的情况下如何操作:

编辑:简化

嗯,我匆忙写了这封信,但没有检查清楚。子选择可能非常慢,但这是我能想到的最短、最简单的SQL语句。等我不那么醉的时候,我可能会说更多

附言:哦,“foo”是我桌子的名字,“food”包含食物的名字,“country”包含国家的名字。样本输出:

   food    |  country   
-----------+------------
 Bratwurst | Germany
 Fisch     | Frankreich
我不喜欢马克斯(.)小组打破联系。。。必须有一种方法将日期合并到联接中,以某种方式任意选择最近的日期

我对这个东西的查询计划感兴趣,如果你在你的实时数据上运行它

试试这个:

select country,food_id, count(*) ne  
from   food f1  
group by country,food_id    
having count(*) = (select max(count(*))  
                   from   food f2  
                   where  country = f1.country  
                   group by food_id)  
Select Country, Food_id
From Munch T1
Where Food_id= 
    (Select Food_id
     from Munch T2
     where T1.Country= T2.Country
     group by Food_id
     order by count(Food_id) desc
      limit 1)
group by Country, Food_id

PostgreSQL在8.4中引入了对的支持,也就是在提出这个问题的第二年。值得注意的是,今天可能会解决如下问题:

SELECT country, food_id
  FROM (SELECT country, food_id, ROW_NUMBER() OVER (PARTITION BY country ORDER BY freq DESC) AS rn
          FROM (  SELECT country, food_id, COUNT('x') AS freq
                    FROM country_foods
                GROUP BY 1, 2) food_freq) ranked_food_req
 WHERE rn = 1;

上述情况将打破僵局。如果你不想断绝关系,你可以用DENSE_RANK()来代替。

我相信这句话能满足你的需要,而且简单明了:

select distinct on (country) country, food_id
from munch
group by country, food_id
order by country, count(*) desc
请让我知道你的想法

顺便说一句,distinct on功能仅在Postgres中可用

例如,源数据:

country | food_id | eaten
US        1         2017-1-1
US        1         2017-1-1
US        2         2017-1-1
US        3         2017-1-1
GB        3         2017-1-1
GB        3         2017-1-1
GB        2         2017-1-1
输出:

country | food_id
US        1
GB        3

现在更简单了:PostgreSQL 9.4引入了
mode()
函数:

select mode() within group (order by food_id)
from munch
group by country
返回(如user2247323的示例):

请参阅此处的文档:


我很想看看这个执行计划与临时表的对比——那些“having”子句是在select检索匹配行后计算的,对吗?看起来可能有很多额外的IO。计划中有几个完整的表扫描,是的。如果你打算在这么长时间后提出一个新的答案,我建议你在一个示例表上尝试,并发布你得到的结果。另外,请提及您正在使用的数据库服务器(mysql或其他)。distinct on功能仅在Postgres中可用,因此,我不确定您将如何在其他数据库中执行类似操作。OP正在使用Postgres,因此它似乎是合适的。我使用op建议的数据库表munch编写了这篇文章,它有三个字段:country(文本)、food_id(int)和eat(date),我认为在大多数地方都需要单引号。
select distinct on (country) country, food_id
from munch
group by country, food_id
order by country, count(*) desc
country | food_id | eaten
US        1         2017-1-1
US        1         2017-1-1
US        2         2017-1-1
US        3         2017-1-1
GB        3         2017-1-1
GB        3         2017-1-1
GB        2         2017-1-1
country | food_id
US        1
GB        3
select mode() within group (order by food_id)
from munch
group by country
country | mode
--------------
GB      | 3
US      | 1