1
select distinct p.product_id from cscart_products p 
    left join product_bikes pb on p.product_id = pb.product_id
    left join cscart_product_options po on po.product_id = p.product_id
    left join cscart_product_option_variants pov on pov.option_id = po.option_id
    left join variant_bikes vb on vb.variant_id = pov.variant_id
    where pb.bike_id = 111 or vb.bike_id = 111 

と:

select distinct p.product_id from cscart_products p 
    left join product_bikes pb on p.product_id = pb.product_id and pb.bike_id = 111
    left join cscart_product_options po on po.product_id = p.product_id
    left join cscart_product_option_variants pov on pov.option_id = po.option_id
    left join variant_bikes vb on vb.variant_id = pov.variant_id and vb.bike_id = 111

異なる結果セットを返すのはなぜですか?

4

2 に答える 2

3

最初のクエリには、WHERE句にORが含まれています。

WHERE pb.bike_id = 111 OR vb.bike_id = 111

2番目のクエリは、条件を介して、代わりに実質的にANDを持ちます。

LEFT JOIN product_bikes pb ON p.product_id = pb.product_id AND pb.bike_id = 111
...
LEFT JOIN variant_bikes vb ON vb.variant_id = pov.variant_id AND vb.bike_id = 111

ボーナスの質問:結合を使用して同じように動作させ、パフォーマンスのために結合を小さくすることでメリットを得る方法はありますか?

クエリを作成する方法はありますが、(私が考えている)メソッドはUNIONを使用しているため、必ずしも高速であるとは限りません。

select distinct p.product_id from cscart_products p 
    left join product_bikes pb on p.product_id = pb.product_id and pb.bike_id = 111
    left join cscart_product_options po on po.product_id = p.product_id
    left join cscart_product_option_variants pov on pov.option_id = po.option_id
    left join variant_bikes vb on vb.variant_id = pov.variant_id -- and vb.bike_id = 111
UNION
select distinct p.product_id from cscart_products p 
    left join product_bikes pb on p.product_id = pb.product_id -- and pb.bike_id = 111
    left join cscart_product_options po on po.product_id = p.product_id
    left join cscart_product_option_variants pov on pov.option_id = po.option_id
    left join variant_bikes vb on vb.variant_id = pov.variant_id and vb.bike_id = 111

次の行に沿ってUNIONサブクエリを作成するなど、おそらくより良い方法があります。

SELECT DISTINCT p.product_id
  FROM      cscart_products                AS p 
  LEFT JOIN cscart_product_options         AS po  ON po.product_id = p.product_id
  LEFT JOIN cscart_product_option_variants AS pov ON pov.option_id = po.option_id
  LEFT JOIN (SELECT vb.product_id FROM variant_bikes AS vb WHERE vb.bike_id = 111
             UNION
             SELECT pb.product_id FROM product_bikes AS pb WHERE pb.bike_id = 111
            ) AS pv ON pv.product_id = p.product_id

cscart_product_options(例では)またはテーブルからデータを選択していないためcscart_product_options_variants、クエリからそれらを削除できます。また、サブクエリを使用したLEFTJOINが適切かどうかも確認する必要があります。内側の結合が必要になる可能性が高いと思います。パフォーマンスを向上させるために実行できる作業は他にもあるかもしれません。

于 2012-08-10T21:36:20.057 に答える
0

ジョナサンが言ったことに加えて。最初のクエリでは、WHEREは、true(pb.bike_id=111またはvb.bike_id=111)でない限り、結果を取得しないように強制します。2番目のクエリでは、LEFT JOINを介して結合できる行は1つだけですが、すべてのDISTINCT[product_id]を取得します。

2番目のクエリと最初のクエリから多くの結果が得られる場合は、その方法です。これを確認する簡単な方法は、SELECTにさらに多くを入れることです。

SELECT p.product_id, pb.bike_id ...

これを行うと、最初のクエリには表示されるすべての製品に111が含まれますが、2番目のクエリにはpb.bike_idに対して多くのNULL値が含まれることに気付くでしょう。

わかる?

于 2012-08-10T21:47:42.557 に答える