簡體   English   中英

Postgres:選擇字段計數大於1的所有行

[英]Postgres: select all row with count of a field greater than 1

我有存儲產品價格信息的表,該表看起來類似於,(不是主鍵)

no   name    price    date
1    paper   1.99     3-23
2    paper   2.99     5-25
3    paper   1.99     5-29
4    orange  4.56     4-23
5    apple   3.43     3-11

現在我想選擇“名稱”字段在表中多次出現的所有行。 基本上,我希望我的查詢返回前三行。

我試過了:

SELECT * FROM product_price_info GROUP BY name HAVING COUNT(*) > 1  

但我收到一條錯誤消息:

列“product_price_info.no​​”必須出現在 GROUP BY 子句中或用於聚合函數

SELECT * 
FROM product_price_info 
WHERE name IN (SELECT name 
               FROM product_price_info 
               GROUP BY name HAVING COUNT(*) > 1)

嘗試這個:

SELECT no, name, price, "date"
FROM (
  SELECT no, name, price, "date",
         COUNT(*) OVER (PARTITION BY name) AS cnt 
  FROM product_price_info ) AS t
WHERE t.cnt > 1

您可以使用COUNT的窗口版本來獲取每個name分區的人口。 然后,在外部查詢中,過濾掉人口少於 2 的name分區。

窗口函數對此非常有用。

SELECT p.*, count(*) OVER (PARTITION BY name) FROM product p;

一個完整的例子:

CREATE TABLE product (no SERIAL, name text, price NUMERIC(8,2), date DATE);

INSERT INTO product(name, price, date) values
('paper', 1.99, '2017-03-23'),
('paper', 2.99, '2017-05-25'),
('paper', 1.99, '2017-05-29'),
('orange', 4.56, '2017-04-23'),
('apple', 3.43, '2017-03-11')
;

WITH report AS (
  SELECT p.*, count(*) OVER (PARTITION BY name) as count FROM product p
)
SELECT * FROM report WHERE count > 1;

給出:

 no |  name  | price |    date    | count
----+--------+-------+------------+-------
  1 | paper  |  1.99 | 2017-03-23 |     3
  2 | paper  |  2.99 | 2017-05-25 |     3
  3 | paper  |  1.99 | 2017-05-29 |     3
(3 rows)

自聯接版本,使用返回多次出現的名稱的子查詢。

select t1.*
from tablename t1
join (select name from tablename group by name having count(*) > 1) t2
  on t1.name = t2.name

基本上與IN / EXISTS版本相同,但可能更快一些。

SELECT name, count(name)
FROM product_price_info
GROUP BY name
HAVING COUNT(name) > 1
LIMIT 3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM