我有三张桌子:
Shop_Table
shop_id
shop_name
Sells_Table
shop_id
item_id
price
Item_Table
item_id
item_name
Sells_Table
通过FK将商品和商店表链接到他们的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
,但如果我包含它,那么我没有得到每个商店的最高价格,而是我得到每个商店的最高价格,项目对是没用。
另外,使用视图的最佳方式是什么?可以通过一个查询来完成吗?
答案 0 :(得分: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;
答案 1 :(得分: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
);
答案 2 :(得分: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
);
答案 3 :(得分: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
的详细信息:
Select first row in each GROUP BY group?
您可以从上面的查询轻松创建VIEW
,性能与原始SQL大致相同。
如果您想要 快速 ,请尝试使用以下多列索引:
CREATE INDEX sells_table_special_idx
ON sells_table (shop_id, price DESC, item_id)
请注意 second 列上的降序 第三个列仅用于使其成为covering index,仅适用于PostgreSQL 9.2或更高版本。
答案 4 :(得分:0)
你的问题听起来有点奇怪,但让我看看我是否可以改写它。
对于每家商店,我想找到他们卖的最贵的东西。从那个项目你想要它的名称,它的价格和销售它的商店。但是,您还声明您使用MIN()获得最低价格......这是最高价还是最低价。无论哪种方式,只需更改min()vs max()
首先只展示商店及其销售的最高价格(或最低价)商品 - 无论它是什么
选择shop_id,max(价格)仅按shop_id分组...以此为基础,然后获得与此最高价格相匹配的商品...商店可以有10件物品,价格为199美元,你有没有任何标识你只想要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