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には「どれかを選ぶ」というものはありません。正当な理由があるわけではありません。決定論的ではないため、アプリケーションをデバッグしようとするとかなりの頭痛の種になります。ただし、1 つを手動で選択することは可能です。プルするには、いくつかの追加のトリックが必要です (一部のデータベースには、それを容易にする拡張機能がありますが、一般的な SQL について言えば)。

したがって、最初に、参加する 1 つの行を選択する基準を選択する必要があります。色がアルファベット順に最初に来るものが欲しいとしましょう (実際の場合、おそらくそのようなものの優先度または重要性があるでしょう)。使用する列は、果物ごとに一意でなければなりません! group-by を使用した別の結合またはネストされた選択によって計算できます。ネストされた選択は、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)各果物の最小色値を持つ行が 1 つだけであることを保証する制約があります。

2 つの結合を使用する別の方法は次のとおりです。

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)

(すべてではありませんが、ほとんどの SQL バリアントのusing (column)省略形です)onetable.column = othertable.column

于 2012-06-21T09:24:07.880 に答える