アイテムのhstore列を含むカートテーブルがあります。この列のエントリの例は次のとおりです。
carts.items row#1 = {
"1614" => {:quantity=>"100", :price_cents=>1655},
"1938" => {:quantity=>"50", :price_cents=>1955},
"1983" => {:quantity=>"100", :price_cents=>2255},
"1322" => {:quantity=>"10", :price_cents=>4455},
"1691" => {:quantity=>"25", :price_cents=>1055},
"1734" => {:quantity=>"20", :price_cents=>1255}
}
carts.items row#2 = {"1614"=>{:quantity=>"50", :price_cents=>1655}}
したがって、私のカートテーブルは次のようになります。
id | items
---------+-------
1 | {"1614"=>{:quantity=>"100", :price_cents=>1655}, "1938" => {:quantity=>"50", :price_cents=>1955},"1983"=>{:quantity=>"100", :price_cents=>2255},"1322"=>{:quantity=>"10", :price_cents=>4455},"1691"=>{:quantity=>"25", :price_cents=>1055},"1734"=>{:quantity=>"20", :price_cents=>1255}}
2 | {"1614"=>{:quantity=>"50", :price_cents=>1655}}
ハッシュに重複したID(1614)が1つあることに気づくでしょうが、その数量は異なります。
アイテムIDカウントと合計数量を含むテーブルを返すクエリを作成したいと思います。次のようになります。
item_id | count | total
---------+-------+------
1614 | 2 | 150
1938 | 1 | 50
1983 | 1 | 50
1322 | 1 | 100
これが私が使っているクエリです:
SELECT
skeys(carts.items) as item_ids,
COUNT(*) AS count,
svals(carts.items) as items
FROM carts
GROUP BY
skeys(carts.items),
svals(carts.items)
それは返します:
item_id | count | total
---------+-------+------
1614 | 1 | {:quantity=>100}
1614 | 1 | {:quantity=>50}
1938 | 1 | {:quantity=>50}
1983 | 1 | {:quantity=>50}
1322 | 1 | {:quantity=>100}
私も試した:
SELECT key, count(*) FROM
(SELECT (each(items)).key FROM carts) AS stat
GROUP BY key
ORDER BY count DESC, key;
これは私にこれを与えます:
item_id | count
---------+-------
1614 | 2
1938 | 1
1983 | 1
1322 | 1
hstore
値内の重複)あなたの問題の根本的な原因はこれで説明されていると思います マニュアルからの引用 :
Hstoreの各キーはuniqueです。重複するキーを使用して
hstore
を宣言すると、1つだけがhstore
に格納され、どちらが保持されるかは保証されません。
大胆な強調鉱山。
単一のhstore
値に同じキーが2つある可能性があると思い込んでいます。
2
のcount
も再現できません。キー1
に対してcount
of 1614
を取得しました。列名としてcount
を使用しないことから始めます。 予約語 です(ただし、Postgresでは許可されています)。
私は得ます(Postgres 9.1.9でテスト済み):
WITH carts AS (
SELECT '"1614"=>{:quantity=>"100"}, "1938"=>{:quantity=>"50"}, "1614"=>{:quantity=>"50"}, "1983"=>{:quantity=>"100"}, "1322"=>{:quantity=>"10"}, "1691"=>{:quantity=>"25"}, "1614"=>{:quantity=>"77"}, "1734"=>{:quantity=>"20"}'::hstore items
)
SELECT key, count(*) AS ct FROM
(SELECT (each(items)).key FROM carts) AS stat
GROUP BY key
ORDER BY ct DESC, key;
結果:
key | ct
------+----
1322 | 1
1614 | 1
1691 | 1
1734 | 1
1938 | 1
1983 | 1
値を集計するには、サブクエリ(またはCTE)が必要です。
簡略化されたテストケース:
CREATE TEMP TABLE carts(c_id serial, items hstore);
INSERT INTO carts(items) VALUES
('"1614"=>"100", "1938"=>"50", "1983"=>"100", "1322"=>"10", "1691"=>"25", "1734"=>"20"')
,('"1614"=>"50"');
クエリ:
SELECT item_ids, count(*) AS ct, sum(items) AS sum_items
FROM (
SELECT (each(items)).key AS item_ids
,(each(items)).value::int AS items -- assuming values can be cast to int
FROM carts
) sub
GROUP BY 1 -- positional parameter is just a notational convenience
ORDER BY 2 DESC;
結果:
item_ids | ct | sum_items
----------+----+-----------
1614 | 2 | 150
1734 | 1 | 20
1691 | 1 | 25
1983 | 1 | 100
1938 | 1 | 50
1322 | 1 | 10