いつも皆さんを悩ませ続けて申し訳ありませんが、SQLはまだ私にとって新しいものです。 Store_location、Product、Sizes、Sells、Available_in、Offers、Currencyのテーブルがあります。目標は、販売された製品のみを返す複数のサブクエリ([〜#〜] [〜#〜]句が必要)で1つのクエリを実行できるようにすることですすべての店舗の場所で、他には何もありません。また、スケーラブルである必要があり、店舗が開いたり閉じたりした場合でも、コードを変更する必要はありません。私は始めるためにこれらのとりとめのない問題を抱えていますが、そこからどこへ行くべきかわかりません。以下の最初の選択ステートメントは、クエリが成功したときに表示する必要があるものです。 SELECT Store_location.store_name、Product.product_name、Sizes.size_option、COUNT(store_location.store_id)AS store_count
JOIN Sells ON Sells.store_location_id = Store_location.store_location_id
JOIN Product ON Product.product_id = Sells.product_id
JOIN ON Available_in.product_id = Product.product_id
JOIN ON Available_in.sizes_id = Sizes.sizes_id
結合を実行して、使用する必要のあるテーブルに外部キー制約がある場所を表示しようとしました。追加情報が必要な場合は、ご提供いたします。関連するすべてのテーブルの内容を表示する link を追加しました。 WHEREステートメントに少なくとも1つのサブクエリを埋め込む必要があることはわかっていますが、そこに何を入れるかわかりません。たくさんの情報をお伝えすることは承知しており、誰にも手伝う時間がない場合は理解しますが、ガイダンスはありがたいです。
私はそれが遅いリクエストであることを理解していますが、誰かが[〜#〜]存在する[〜#〜]を使用する方法で私を助けることができれば、私は非常に感謝します。
全店で販売されている商品を探すのが一番難しいようです。ほとんどの場合と同様に、これを行う方法は複数ありますが、次のクエリは、すべての店舗で販売されているすべての製品IDを返します。
SELECT product_id
FROM Product
EXCEPT -- exclude product IDs that are not sold in all stores
SELECT product_id
FROM (-- Generate list of product IDs and the stores that do NOT sell them
-- select all possible products and stores ...
SELECT product_id, store_id
FROM Product CROSS JOIN Store_location
EXCEPT -- ... for the products actually sold by each store
SELECT product_id, store_id
FROM Sells
) Not_At_All_Stores
サブクエリは、可能なすべての商品と店舗のリストを取得し、対象の店舗で実際に販売された商品を表すコンボを削除します。これは、指定された店舗で販売されていない製品のみを残します。
次に、製品の完全なリストを取得し、少なくとも1つのストアで販売されていない(現在)とわかっている製品をすべて削除します。それはすべての店で販売された製品を残すだけです。
ここからは、すべてを結合するだけです。次のようなFROM句で終了します。
SELECT Store_location.store_name
,Product.product_name
,Sizes.size_option
FROM (
SELECT product_id
FROM Product
EXCEPT -- exclude product IDs that are not sold in all stores
SELECT product_id
FROM (-- Generate list of product IDs and the stores that do NOT sell them
-- select all possible products and stores ...
SELECT product_id, store_id
FROM Product CROSS JOIN Store_location
EXCEPT -- ... for the products actually sold by each store
SELECT product_id, store_id
FROM Sells
) Not_At_All_Stores
) uprod -- for a Universally sold PRODuct
INNER JOIN Product ON (uprod.product_id = Product.product_id)
INNER JOIN Available_in ON (uprod.product_id = Available_in.product_id
INNER JOIN Sizes ON (Available_in.size_id = Sizes.size_id)
INNER JOIN Sells ON (uprod.product_id = Sells.product_id)
INNER JOIN Store_location ON (Sells.store_id = Store_location.store_id)
ORDER BY store_name, product_name, size_option
WHERE
句は必要ありません(要求した内容に基づく)。店舗情報は冗長であることに注意してください。これらの製品はすべての店舗で販売されているため、5つの店舗名のいずれかが各コピーの前に付加された、同じ基本結果の5つのコピーを取得しているだけです。店舗名は、すべての店舗でされていないが販売されている製品の方がはるかに興味深いものです。
注:Product
テーブルのインデックス付け方法に応じて、product_name
列をNot_At_All_Stores
サブクエリに追加し、そこから引き継ぐことができます。ただし、これは、すべての可能な製品およびストアのリストにそれを含める必要があることを意味します。これにより、EXCEPT操作を実行するときに、より多くのメモリが消費されます。
更新:最新のコメントから明らかなように、この割り当てでは、WHERE句、WHERE句のサブクエリ、およびEXISTSを使用する必要があります。ここからそこに行くには:
uprod
を削除します。 uprod.product_id
にリンクされているものはすべてProduct.product_id
にリンクする必要があります。これはisの宿題なので、少なくとも実際に組み立ててみましょう。
私の回答の最初のクエリをサブクエリとして使用し、製品を探します
これは、HAVING
句を使用して解決できます。
with cte as(
Select
p.product_id
,p.product_name
from
Product p
inner join
sells s on
s.product_id = p.product_id
group by
p.product_id
,p.product_name
having count(p.product_id) = (select count(distinct store_location_id) from sells))
select
c.product_id
,c.product_name
,s.store_location_id
,a.sizes_id
from
cte c
inner join
sells s on
s.product_id = c.product_id
inner join
Avaliable_in a on
a.product_id = c.product_id