0

私は3つのテーブルを持っています:

Shop_Table
   shop_id
   shop_name

Sells_Table
   shop_id
   item_id
   price

Item_Table
   item_id
   item_name

Sells_TableFK を介して item テーブルと shop テーブルを ID にリンクします。各店舗から最も高価なアイテム、つまりフォームの出力を取得しようとしています。

(shop_name, item_name, price)
(shop_name, item_name, price)
(shop_name, item_name, price)
(shop_name, item_name, price)
...

ここで、price は各ショップの最大価格アイテムです。(shop_name, max(price)) を達成できるようですが、item_name を含めようとすると、shop_name のエントリが複数取得されます。私の現在の方法は

create view shop_sells_item as
select s.shop_name as shop, i.item_name as item, price
from Shop_Table s
join Sells_Table on (s.shop_id = Sells_Table.shop_id)
join Item_Table i on (i.item_id = Sells_Table.item_id);

select shop, item, max(price)
from shop_sells_item
group by shop;

ただし、 というエラーが表示されますがitem must appear in the GROUP BY clause or be used in an aggregate function、それを含めると、各ショップの最大価格が取得されず、代わりに各ショップ、アイテムのペアの最大価格が取得されますが、これは役に立ちません。

また、ビューを使用するのが最善の方法ですか? 単一のクエリで実行できますか?

4

5 に答える 5

2

Postgresql の方法で実行できます。

select distinct on (shop_name) shop_name, item_name, price 
from shop_table
join sells_table using (shop_id) 
join item_table using (item_id)
order by shop_name, price;
于 2013-09-28T10:56:25.977 に答える
1

各店舗で一番高い商品を仕入れようとしていますが、

あるショップの最も高価なアイテムの定義:= このショップには、より高価なアイテムはありません

SELECT *
FROM Sells_Table st
WHERE NOT EXISTS (
    SELECT * FROM Sells_Table nx
    WHERE nx.shop_id = st.shop_id
    AND nx.price > st.price
);

これで、必要なアイテム(結果セットのスケルトン)に対応する Sells_table エントリができました。を追加するだけです:

SELECT sh.shop_name -- <<-- Meat
    , it.item_name  -- <<-- Meat
    , st.price
FROM Sells_Table st
JOIN shop_table sh ON sh.shop_id = st.shop_id  -- <<-- Meat
JOIN items_table it ON it.item_id = st.item_id -- <<-- Meat
WHERE NOT EXISTS (
    SELECT * FROM Sells_Table nx
    WHERE nx.shop_id = st.shop_id
    AND nx.price > st.price
);
于 2013-09-28T11:55:20.087 に答える
1

おそらく最速:

SELECT s.shop_name, i.item_name, sub.price
FROM  (
   SELECT DISTINCT ON (shop_id) shop_id, item_id, price 
   FROM   sells_table
   ORDER  BY shop_id, price DESC -- , item_id -- for 1 item only
   ) sub
JOIN   item_table i USING (item_id)
JOIN   shop_table s USING (shop_id);
  • 取得the most expensive item from each storeするには、する必要がありますORDER BY .. price DESC

  • 上記のクエリは、最大価格を共有するショップのすべてのアイテムを返します。複数の場合があります。常に単一のアイテムが必要な場合は、同点を解消する方法を定義する必要があります。たとえば、ORDER BY上記の追加項目のコメントを外して、最小のものを選択しますitem_id

  • 一般に、最初に集計 (または選択) してから、集計または選択自体に関係のない追加のテーブルに結合する方が高速です。

DISTINCT ONこの関連する回答の詳細:
各 GROUP BY グループの最初の行を選択しますか?

上記のクエリから簡単に作成できVIEW、パフォーマンスは生の SQL とほぼ同じです。

トップパフォーマンスの指標

その高速が必要な場合は、次のような複数列のインデックスを試してください。

CREATE INDEX sells_table_special_idx
ON sells_table (shop_id, price DESC, item_id)

2 番目の列の降順に注意してください。3 番目
の列は、PostgreSQL 9.2 以降でのみ機能するカバリング インデックスにするためだけに機能します。

于 2013-09-28T13:17:22.767 に答える
1

以下のクエリは、1 つのストア内の複数のアイテムの最高価格が同じ (すべて最も高価なアイテム) という状況を扱っていないことに注意してください。

SELECT
    s.shop_name,
    i.item_name,
    si.price
FROM
    Sells_Table si
JOIN
    Shop_Table s
ON
    si.shop_id = s.shop_id
JOIN
    Item_Table i
ON
    si.item_id = i.item_id
WHERE
    (shop_id, price) IN (
        SELECT
            shop_id,
            MAX(price) AS price_max
        FROM
            Sells_Table
        GROUP BY
            shop_id
    );
于 2013-09-28T12:25:42.607 に答える
0

あなたの質問は少し奇妙に聞こえますが、言い換えることができるかどうか見てみましょう.

店舗ごとに、販売している最も高価なものを見つけたいと考えています。そのアイテムから、そのアイテムの名前、価格、および販売店が必要です。ただし、最低価格に MIN() を使用していると述べています...どちらが最高価格か最低価格かです。いずれにせよ、min() と max() を変更するだけです

最初は店舗と、販売する最大価格 (または最小) の商品から始めます。

shop_id のみでグループ化された shop_id, max(price) を選択します...これを基準として使用して、この最大価格に一致するアイテムを取得します...ショップには 199 ドルで 10 個のアイテムがあり、あなたを識別するものは何もありません1とそれを処理する基準のみが必要です。私は取得しています

select
      FindingMax.Shop_id,
      shop.shop_name,
      FindingMax.HighestPrice,
      Item_Table.item_name
   from
      ( select st.shop_id,
               max( st.price ) as HighestPrice
           from
               sells_table st
           group by
               st.shop_id ) as FindingMax
      JOIN Shop_Table shop
         on FindingMax.shop_id = shop.shop_id
      JOIN sells_table st2
         on FindingMax.shop_id = st2.shop_id
         AND FindingMax.HighestPrice = st2.price
         JOIN Item_Table
            on st2.item_id = Item_Table.item_id
于 2013-09-28T11:31:26.263 に答える