2016-04-01 9 views
3

より大きなフィールドのカウントを持つすべての行を選択し、テーブルには、のようになります(なしが主キーである)のPostgres:私は、製品の価格情報を格納するテーブルを持っている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 

は、今私が選択したいです「名前」フィールドがテーブル内に複数回現れたすべての行。基本的には、最初の3つの行を返すクエリが必要です。

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

が、私はというエラーを取得:

は、私が試した

コラム "product_price_info.no​​は" GROUP BY句に現れなければならないか、集約関数で使用することが

答えて

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

試用:

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パーティションを除外します。

2

自己結合バージョンでは、複数回表示される名前を返すサブクエリを使用します。

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

基本的には少し速くIN/EXISTSバージョン、おそらく同じ。

0

Window Functionsです。完全例えば

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') 
; 

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

を与える:

no | name | price | date | count 
----+--------+-------+------------+------- 
    5 | apple | 3.43 | 2017-03-11 |  1 
    4 | orange | 4.56 | 2017-04-23 |  1 
    1 | paper | 1.99 | 2017-03-23 |  3 
    2 | paper | 2.99 | 2017-05-25 |  3 
    3 | paper | 1.99 | 2017-05-29 |  3 
(5 rows) 
関連する問題