列必须出现在GROUP BY子句中或在聚合函数中使用(PostgreSQL)

时间:2018-11-06 00:35:36

标签: postgresql

我有这个银行信息数据库:

  id    | date     |     asset           
--------+----------+---------------
 1      | 6/30/2001|    333860 
 1      | 3/31/2001|    336896
 1      | 9/30/2001|    349343
 2      | 6/30/2001|    451297
 2      | 3/31/2001|    411421
 2      | 9/30/2001|    430178
 3      | 6/30/2001|    106506
 3      | 3/31/2001|    104196
 3      | 9/30/2001|    106383

我正在尝试显示总资产第二高的银行的ID。这是我使用的代码(类似于question

SELECT DISTINCT(id), SUM(asset) AS mv 
FROM bank2001 
WHERE asset NOT IN (SELECT MAX(asset) FROM bank2001)

运行查询时,收到以下错误:

  

错误:“ bank2001.id”列必须出现在GROUP BY子句中或   用于集合函数第1行:SELECT DISTINCT(id),MAX(asset)   AS mx

我已经查询了此错误,但是由于我的代码中没有GROUP BY,因此我找不到关于它与该问题的关系的任何信息。此错误是什么意思,我该如何解决此问题?

注意:该代码应该返回ID 1。

3 个答案:

答案 0 :(得分:0)

第一个Distinct不是Aggregate函数。它将删除重复项,但不会删除Aggregate。并且您拥有Sum()的{​​{1}}函数,因此需要Aggregate

Group By

这里是结果:Fiddle

编辑

SELECT 
    DISTINCT(id), SUM(asset) AS mv 
FROM 
    bank2001 
WHERE 
    asset NOT IN (SELECT 
                     MAX(asset) 
                  FROM 
                     bank2001)
GROUP BY
     id

在评论中。.SELECT id, SUM(asset) AS mv FROM bank2001 WHERE asset NOT IN (SELECT MAX(asset) FROM bank2001) GROUP BY id 将按Group显示,因此ID不需要。。

您可以看到相同的结果:Fiddle

答案 1 :(得分:0)

除了您遇到的“分组依据”问题外,该查询也不会做您想要的事情,因为这一点

WHERE asset NOT IN (SELECT MAX(asset) FROM bank2001)

只是从数据库中删除第四行。您需要将其视为两个单独的任务-首先找到每个银行的总金额,然后在这些金额中找到第二大的金额。这样的事情(还有其他方法,但这最接近您的原始查询)

--This part gets the asset totals for each bank - returns one row per bank
WITH BankAssets as (
    Select id, SUM(asset) AS assetTotal
    FROM bank2001
    GROUP BY id
)
-- This part returns the top bank that does not have the maximum asset sum
Select id
From BankAssets
WHERE assetTotal NOT IN (SELECT MAX(assetTotal) FROM BankAssets) --skip any banks with the top amount
ORDER BY assetTotal DESC  --order in descending order
LIMIT 1  --only return one row

请注意,如果按资产总额排名前2名的银行的金额相同,则将获得第3家。

答案 2 :(得分:0)

一个表和一些要开始的行。 (您应该在问题中添加它。)

create table bank2001 (
  id integer,
  date date,
  asset integer,
  primary key (id, date)
  );

  insert into bank2001 values
 (1, '6/30/2001',    333860), 
 (1, '3/31/2001',    336896),
 (1, '9/30/2001',    349343),
 (2, '6/30/2001',    451297),
 (2, '3/31/2001',    411421),
 (2, '9/30/2001',    430178),
 (3, '6/30/2001',    106506),
 (3, '3/31/2001',    104196),
 (3, '9/30/2001',    106383);

此查询返回每个ID的总资产。

select id, sum(asset) as total_assets
from bank2001
group by id
order by total_assets desc

id  total_assets
2   1292896
1   1020099
3   317085
  

我正在尝试显示总资产第二高的银行的ID。

很明显,正确的答案是1。您正在尝试返回第二行的ID。一种方法是告诉PostgreSQL您想返回第一行,而您想跳过第一行来获取它。

with total_assets as (
  select id, sum(asset) as total_assets
  from bank2001
  group by id
)
select id
from total_assets
order by total_assets desc
limit 1 offset 1;