我有一个问题要求
餐桌水果
FruitID | Fruit | Unit Price
1 | Orange | $3
2 | Apple | $2
3 | Grape | $4
表FruitDetails
Picture | Color | FruitID
Orange_o.jpg | Orange | 1
Apple_g.jpg | Green | 2
Apple_r.jpg | Red | 2
Grape_p.jpg | Purple | 3
Grape_g.jpg | Green | 3
我想得到的结果是没有重复名字的所有成果。
实施例
Fruit | UnitPrice | Picture | Color
Orange| $3 | Orange_o.jpg | Orange
Apple | $2 | Apple_g.jpg | Green
Grape | $4 | Grape_p.jpg | Purple
这有可能实现吗? 感谢
答案 0 :(得分:1)
为SQL Server编写,但实际查询应该适用于其他数据库。
设置数据:
declare @Fruit table (FruitID int not null,Fruit varchar(10) not null,UnitPrice int not null)
insert into @Fruit(FruitID,Fruit,UnitPrice) values
(1,'Orange',3),
(2,'Apple',2),
(3,'Grape',4)
declare @FruitDetails table (FruitID int not null,Picture varchar(20) not null,Color varchar(10) not null)
insert into @FruitDetails (FruitID,Picture,Color) values
(1,'Orange_o.jpg','Orange'),
(3,'Grape_p.jpg','Purple'),
(3,'Grape_g.jpg','Green'),
(2,'Apple_g.jpg','Green'),
(2,'Apple_r.jpg','Red')
查询:
select
f.Fruit,
f.UnitPrice,
fd.Picture,
fd.Color
from
@Fruit f
inner join
@FruitDetails fd
on
f.FruitID = fd.FruitID
left join
@FruitDetails fd_anti
on
f.FruitID = fd_anti.FruitID and
fd_anti.Picture < fd.Picture --This is the condition for picking a better row
where
fd_anti.FruitID is null --This eliminates rows where a better row was picked
结果:
Fruit UnitPrice Picture Color
---------- ----------- -------------------- ----------
Orange 3 Orange_o.jpg Orange
Grape 4 Grape_g.jpg Green
Apple 2 Apple_g.jpg Green
哪个与您的预期结果不符,但您没有给我们一个关于从FruitDetail
选择“最佳”行的条件的良好定义。
答案 1 :(得分:1)
SQL中没有“挑选任何一个”。这不是有充分理由的;它不会是确定性的,这会让你很头疼试图调试你的应用程序。然而,可以手动选择一个,它只需要一些额外的技巧(一些数据库有扩展,可以使它更容易,但谈到通用SQL)。
首先,您必须选择一个标准来选择要加入的一行。假设您希望首先按字母顺序排列颜色(在实际情况下,您可能具有某些优先级或重要性)。您使用的列对于每个水果必须是唯一的!您可以通过group-by或嵌套select的另一个连接来计算它。嵌套选择是IMO更容易编写和理解。它将是:
(select min(Color) from FruitDetails as inner where inner.Fruit = Fruit.Fruit)
现在你加入带有条件的表,颜色就是那个,所以:
select * from Fruit
join FruitDetails as outer
on outer.Fruit = Fruit.Fruit
and outer.Color = (select min(Color) from FruitDetails as inner where inner.Fruit = Fruit.Fruit)
这假设FruitDetails
表中有一个Fruit
列,您忘了,但如果没有该列,则根本无法进行连接。并且它有一个unique(Fruit, Color)
约束,以保证每个水果只有一行具有最小颜色值。
另外两个连接的替代方案是:
select Fruit.* ThisDetails.*
from Fruit
join FruitDetails as ThisDetails using (Fruit)
join FruitDetails as BestDetails using (Fruit)
group by Fruit.*, ThisDetails.*
having ThisDetails.Color = min(BestDetails.Color)
(using (column)
是onetable.column = othertable.column
的缩写,在大多数但不是全部的SQL变体中)