1

次のステートメントがあります。

(SELECT res_bev.bev_id, property_value.name AS priority 
    FROM res_bev, bev_property, property_value 
    WHERE res_bev.res_id='$resIn'
        AND bev_property.bev_id=res_bev.bev_id
        AND bev_property.type_id='23'
        AND property_value.id=bev_property.val_id)
UNION
(SELECT res_bev.bev_id, property_value.name as priority 
    FROM res_bev, bev_property, property_value 
    WHERE res_bev.res_id='$resIn' 
        AND bev_property.bev_id=res_bev.bev_id 
        AND bev_property.type_id='22' 
        AND property_value.id=bev_property.val_id)

3 つのテーブルがあります。

res_bev
res_id | bev_id | ID

Bev_property
type_id | val_id | bev_id | ID

プロパティ値
の名前 | ID

私が探しているのは、ガラスの価格(type_id = '23')、次にボトルの価格(type_id = '22')で注文される結果ですが、最初の選択が返さ3456 | 7.5れ、2番目の返されるという事実のために、ユニオンには重複が含まれているようです3456 | 55価格/グラスは 7.5 で、価格/ボトルは 55 です。これらの重複を 2 番目の SQL ステートメントから削除して、テーブルを返すにはどうすればよいですか?

また、左結合を介して疑似テーブルを作成して のテーブルを作成することにだまされましたがbev_id | price/Glass | price/Bottle、これは複数の価格タイプに拡張できるはずなので、UNION の方が効率的であると考えました。正しい方向に押すだけで役に立ちます。

4

2 に答える 2

1

私が何かを逃している場合、またはあなたがあなたの質問から持っている場合を除いて

SELECT res_bev.bev_id, 
       property_value.name AS priority 
FROM res_bev, bev_property, property_value 
WHERE res_bev.res_id='$resIn' 
AND bev_property.bev_id=res_bev.bev_id 
AND (bev_property.type_id='23' OR bev_property.type_id='22')
AND property_value.id=bev_property.val_id)
order by bev_property.type_id desc

ユニオンを注文したい場合はPS

の線に沿って何かを試してみてください

Select * from
(
select ...
Union
select ...
) somenameforqryinparentheses
Order by Somecolumn1, somecolumn2
于 2012-06-18T22:02:18.977 に答える
1

bev_property.type_idを指定して、内部の値を持つIN()句と照合することにより、1つのクエリでそれを行うことができます。

最初に見つかったものだけを返すには、付随するフィールドのDISTINCTSELECTが必要ですbev_id

それらを注文するには、適切な降順のORDERBY句を追加するだけです。これは最初に順序付けし、2番目の値をフィルターで除外する必要がありbev_property.type_idます。(データベースは、指示がない限り、特定の順序で何かを返すことはありません。内部規則がある場合や、そうであるように見える場合もありますが、ステートメントでORDER BY句を指定しない限り、これが繰り返し可能であるとは限りません。)SELECT

SELECT DISTINCT res_bev.bev_id, property_value.name AS priority 
FROM res_bev, bev_property, property_value 
WHERE res_bev.res_id='$resIn'
    AND bev_property.bev_id=res_bev.bev_id
    AND bev_property.type_id IN ('23','22')
    AND property_value.id=bev_property.val_id
ORDER BY bev_property.type_id DESC;

UNIONは、ルックアップ全体を2回実行する必要があるため、実際には高速ではありません。このフィールドにインデックスが付けられていない場合は、1つのテーブルトラバーサルを実行するのではなく、1つの要素に対して2回一致するテーブル全体のトラバーサルを実行します。 2つの要素と一致します。(テーブル全体を歩くのは一般的に遅く、単純な要素を互いに一致させません)

適切にインデックスを作成すると、新しいselectクエリを実行し、クエリアナライザを再度実行するオーバーヘッドがわずかに発生する可能性があると思いますが、よくわかりません。クエリ間の類似点を認識するのに十分賢いので、問題にはなりません。

ただし、特定のデータベースを試してみるのは必ずしも害はありません。さまざまなステートメントでクエリの最適化を試みるときはいつでも、 EXPLAINでそれらを使用すると、クエリが何を実行するか、テーブル全体を調べたり、ファイルのデータを並べ替えたりするかどうかがわかります...

于 2012-06-18T21:58:34.380 に答える