Postgresql 选择不在计数中的其他列,分组依据

Postgresql 选择不在计数中的其他列,分组依据,postgresql,Postgresql,所以我有一张桌子如下 product_id sender_id timestamp ...other columns... 1 2 1222 1 2 3423 1 2 1231 2 2 890 3 4

所以我有一张桌子如下

product_id      sender_id      timestamp      ...other columns...
1               2              1222
1               2              3423
1               2              1231
2               2              890
3               4              234
2               3              234234
我想得到sender_id=2的行,但我想按产品_id进行计数和分组,并按时间戳降序排序。这意味着我需要以下结果

product_id      sender_id      timestamp      count      ...other columns...
1               2              3423           3
2               2              890            1
我尝试了以下查询:

SELECT product_id, sender_id, timestamp, count(product_id), ...other columns...
FROM table
WHERE sender_id = 2
GROUP BY product_id
但是我在查询中得到以下错误
错误:列“table.sender\u id”必须出现在GROUP BY子句中或在聚合函数中使用

似乎我无法选择不在GROUP BY中的列。我在网上找到的另一个方法是加入

SELECT product_id, sender_id, timestamp, count, ...other columns...
FROM table
JOIN (
    SELECT product_id, COUNT(product_id) AS count
    FROM table
    GROUP BY (product_id)
) table1 ON table.product_id = table1.product_id
WHERE sender_id = 2
GROUP BY product_id

但这样做只是列出所有行,没有分组或计数。我的猜测是ON部分只是再次扩展了表。

尝试使用
产品标识、发送者标识进行分组

select product_id, sender_id, count(product_id), max(timestamp) maxtm 
from t
where sender_id = 2
group by product_id, sender_id
order by maxtm desc
如果还需要其他列:

select t.*, t1.product_count
from t
inner join (
    select product_id, sender_id, count(product_id) product_count, max(timestamp) maxtm 
    from t
    where sender_id = 2
    group by product_id, sender_id
) t1
on t.product_id = t1.product_id and t.sender_id = t1.sender_id and t.timestamp = t1.maxtm
order by t1.maxtm desc

只需利用您的数据进行训练:

CREATE TABLE products (product_id INTEGER,
sender_id INTEGER,
time_stamp INTEGER)

INSERT INTO products VALUES
(1,2,1222),
(1,2,3423),
(1,2,1231),
(2,2,890),
(3,4,234),
(2,3,234234)

SELECT  product_id,sender_id,string_agg(time_stamp::text,','),count(product_id) 
FROM products
WHERE sender_id=2
GROUP BY product_id,sender_id
这里您有不同的时间戳,所以您需要应用一些聚合,或者只是删除select语句中的该列

如果删除select语句中的time_戳记,将非常容易,如下所示:

SELECT  product_id,sender_id,count(product_id) 
FROM products
WHERE sender_id=2
GROUP BY product_id,sender_id

sender\u id=2
product\u id=1
有3个不同的
时间戳
,因此您需要为
order by
选择哪一个
时间戳?@OtoShavadze最新的一个(最大的一个)有效,但仍然会遇到返回其他列的问题(例如,如果您必须返回多个列)您只需将select语句中没有任何聚合操作的group by子句中的所有唯一列放在一起。假设正确,但有一个问题,将发送方id=2的位置保留在join中有什么区别,
t.sender\u id=t1.sender\u id
在它之外,在忽略这两个变量和保持
之间,其中t.sender\u id=2
在打开之后clause@pewpewlasers-结果应该相同,但性能(和执行计划)可能不同,不确切,需要测试,只有“大”表才值得注意。此外,您还可以删除发送方id=2的
,因为这是
内部连接
,所以将该筛选器移动到
ON
子句中,例如:
ON t.product\u id=t1.product\u id和t.timestamp=t1.maxtm和t.sender\u id=2