在表A(别名ai)中,我有一个项目列表。在表B(别名aib)中,我有表A的所有项目的价格历史,但不是所有项目,对于那些,我需要SELECT NULL。我需要从表A中选择项目,它是表B中的最高价格或NULL。
这就是我所拥有的,但它不是很有用,如果表B有广泛的价格历史,我会得到重复的记录。
以下是不完全正常的查询:
SELECT *
FROM ItemGroup aig
INNER JOIN Item ai ON ai.groupID = aig.ID
LEFT JOIN Item_Prices aib ON ai.ID = aib.ItemID
WHERE aig.ID = @groupID AND
(aib.max_price = (SELECT MAX(price) AS highprice FROM Item_Prices
WHERE ItemID = ai.ID)
OR aib.price IS NULL)
ORDER BY end_date
欢迎所有建议。
此致,
雷
答案 0 :(得分:1)
SELECT *
FROM ItemGroup aig
INNER JOIN Item ai ON ai.groupID = aig.ID
LEFT OUTER JOIN (
SELECT
ItemID,MAX(max_price)
FROM Item_Prices
GROUP BY ItemID
) aib ON ai.ID=aib.ItemID
WHERE aig.ID = @groupID
ORDER BY end_date
子查询按ItemID获取最高价格,因此应过滤掉重复项。
答案 1 :(得分:1)
Ray,您是否只是使用item表将两个表连接在一起?如果您在查询的其余部分中不需要项目表中的任何其他内容,那么它就没有必要。
如果所有你真正想做的是“选择表A中的项目,它是表B中的最高价格或NULL。”如果Item_Prices.price允许null,那么就可以这么简单。
SELECT a.ItemName, MAX(b.price) AS 'MaxPrice'
FROM Item AS a INNER JOIN Item_Prices AS b
ON a.groupID = b.ItemID
GROUP BY a.ItemName
以下是我的Item_Prices表格中的内容
以下是我的项目表
中的内容
查询结果:
以下是我的Item表的设计视图,groupID是主键。
这是我的Item_Prices表的设计视图,您可以将ItemID设置为外键
如果要从单独的表中选择数据,则不需要第三个表来为您或任何内容链接它们。只要表A中有某种类型的唯一标识符(主键)和表B中链接的匹配键(通常是外键),你就是金色的!
如果你打算将那个第三张桌子放到另一个场地,那么就不要理会了!我只是想举起一个简单的例子向你展示,因为当我在工作/学校时我看到很多人使用第三个表将表连接在一起,大部分时间都没有意义!
答案 2 :(得分:1)
@squillman几乎已经钉了它。优化
SELECT GroupID = aig.groupID ,
ItemID = ai.ID as ItemID ,
HighestPrice = aib.HighestPrice
FROM Item ai
left join ( select ItemID ,
HighestPrice = max(price)
from Item_Prices
group by ItemID
) aib on aib.ItemID = ai.ID
WHERE ai.groupID = @groupID
ORDER BY end_date
如果您从表ItemGroup中查看的是组ID ...您不需要该表:您已经在Item表中获得了groupID,因此ItemGroup是不必要的,尽管您需要如果您需要ItemGroup中的其他属性,请保留它。保留ItemGroup不会对查询计划造成太大影响:您最多只需要一个组,并且可能ItemGroup在groupID上有覆盖索引。
子查询不需要 distinct
:group by ItemID
使子查询结果集由ItemID唯一。这对性能有影响:distinct
表示引擎必须确保结果集是唯一的。希望优化器会意识到group by
使该集唯一并丢弃distinct
,但我不会指望它。
答案 3 :(得分:0)
Select ...
From ItemGroup As AIG
Join Item As AI
On AI.ID = AIG.ID
Where AIG.Id = @groupId
And Exists (
Select 1
From Item_Prices As IP1
Join (
Select IP2.ItemID, Max( IP2.Price ) As Price
From Item_Prices As IP2
Group By IP2.ItemId
) As MaxPrices
On MaxPrices.ItemID = IP1.ItemID
And MaxPrices.Price = IP2.Price
Where IP1.ItemID = AI.ID
Union All
Select 1
From Item_Prices As IP1
Where IP1.ItemID = AI.ID
And IP1.Price Is Null
)
Order By End_Date