2012-06-21 126 views
0

我有一个查询问DISTINCT与INNER JOIN

表水果

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 

这是可能做到这一点? 谢谢

+4

什么是你加盟吗?你现在查询的是什么样子? –

+0

如何从'FruitDetails'中选择正确的行?你怎么知道葡萄是紫色的而苹果是绿色的? –

+0

wats的逻辑? – manurajhada

回答

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中挑选“最佳”行的条件的定义。

+0

使用左连接的缺点是您正在限制查询优化器。通过嵌套选择或其他,分组,连接选择“最佳”图片限制它较少。 –

+0

@JanHudec - 如果找到“最佳”结果行需要复杂的多列条件,我可以用反连接表示它,但不能用嵌套选择表示。 –

+0

是的,如果您无法计算代表订单的数字或值,则可以使用嵌套选择,也不是真正的分组连接。 –

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变种)