0

我有一个问题要问

餐桌水果

 FruitID |  Fruit  | Unit Price 
    1    |  Orange |     $3
    2    |  Apple  |     $2
    3    |  Grape  |     $4

餐桌水果详情

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

2 回答 2

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.

于 2012-06-21T09:23:09.840 回答
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 变体的缩写)

于 2012-06-21T09:24:07.880 回答