5

次の2つのMySQLテーブルがあります

  • 製品 (product_id、名前、カテゴリ)
  • products_sizes (商品 ID、サイズ)

すべての製品は複数のサイズを持つことができます

クエリを作成する必要があります

  1. カテゴリとサイズ (サイズが設定されている場合) に基づいて製品を選択します - 例: カテゴリ = '靴' およびサイズ = '10'
  2. 商品のすべてのサイズを返す必要がありますが、商品に特定のサイズがある場合に限ります。
  3. 同時に、製品の結果をオフセットのある特定の数に制限する必要があります

私は今、以下のクエリを持っています。私は動作しますが、カテゴリによって制約されず、指定された 1 つのサイズ (ここでは「10」) のみが返されます。すべてのサイズが必要ですが、サイズに「10」がある製品のみが必要です...

SELECT products.*
     , products_sizes.*
FROM (
   SELECT *
   FROM products 
   LIMIT $limit OFFSET $offset
   ) AS products
LEFT JOIN products_sizes 
   ON products.products_id = products_sizes.products_id 
WHERE products_sizes.size = 10

...そして、WHERE category = 'something'クエリを追加すると、何も返されません...

SELECT products.*
     , products_sizes.*
FROM (
   SELECT * 
   FROM products 
   WHERE category = 'shoes' 
   LIMIT $limit OFFSET $offset
   ) AS products
LEFT JOIN products_sizes 
   ON products.products_id = products_sizes.products_id
WHERE products_sizes.size = 10

??

更新: 近づいています...

答えを読んだ後、私は今これを持っています:

SELECT *
FROM products AS p 
LEFT JOIN products_sizes AS s 
    ON p.product_id = s.product_id
    WHERE s.product_id 
        IN (SELECT product_id FROM s WHERE size = 10)
    AND p.category = 'shoes'

最初の質問の最初の 2 つの要件を満たしています。

  1. カテゴリとサイズによって制限された結果を返します
  2. サイズの 1 つが指定されたサイズと等しい場合、各商品のすべてのサイズを返します

...しかし、結果を特定の数の製品に制限する必要があります。クエリの最後に LIMIT $limit を配置すると、製品の数ではなく、返されるサイズの数が制限されます...ご意見ありがとうございます。

4

4 に答える 4

1

メインクエリのWHERE句は、の目的を無効にLEFT JOINして、と同じにしていINNER JOINます。一致する派生テーブルによって選択された行がない可能性が非常に高いです (サイズ 10 の靴)。

表示されていないデータに関する何かがない限り、これを試すことができます。

SELECT products.*
     , products_sizes.*
FROM products 
JOIN products_sizes 
   ON products.products_id = products_sizes.products_id
WHERE products.category = 'shoes' 
   AND products_sizes.size = 10
LIMIT $limit OFFSET $offset
于 2013-01-20T17:00:28.120 に答える
0

少なくとも 3 つの結果形式が必要になる場合があります。

  1. サイズごとに 1 行、ただし 10 個の異なる商品に限定
  2. 10 行 - カンマ区切りのサイズを含む列を含む商品ごとに 1 行
  3. PHP で結合される 2 つの結果セット:
    • 10 製品
    • 関連サイズ

フォーマットごとに、条件に一致する 10 個の異なる製品を返す必要があります。

最も表現力のある方法は、EXISTS ステートメントを使用することです。

select p.*
from products p
where p.category = 'shoes'
and exists (
    select *
    from products_sizes ps
    where ps.product_id = p.product_id
      and ps.size = 10
)
order by p.product_id
limit $limit offset $offset

もう 1 つの方法は、JOIN を使用することです。

select p.*
from products p
join products_sizes ps
  on ps.product_id = p.product_id
where p.category = 'shoes'
  and ps.size = 10
order by p.product_id
limit $limit offset $offset

コードがコンパクトなため、2番目のものをさらに使用します。ただし、いつでも EXISTS ステートメントに置き換えることができます。

1.

select p.*, ps.size
from (
    select p.*
    from products p
    join products_sizes ps
      on ps.product_id = p.product_id
    where p.category = 'shoes'
      and ps.size = 10
    order by p.product_id
    limit $limit offset $offset
) p
join products_sizes ps
  on ps.product_id = p.product_id
order by p.product_id, ps.size

2.

select p.*, group_concat(ps.size order by ps.size) as sizes
from products p
join products_sizes ps1
  on ps1.product_id = p.product_id
join products_sizes ps
  on ps.product_id = p.product_id
where p.category = 'shoes'
  and ps1.size = 10
group by p.product_id
order by p.product_id
limit $limit offset $offset

explode()PHP で文字列を配列に変換するために使用できます。

$product->sizes = explode(',' $product->sizes);

3.

select p.*
from products p
join products_sizes ps
  on ps.product_id = p.product_id
where p.category = 'shoes'
  and ps.size = 10
limit $limit offset $offset

製品 ID でインデックス付けされた配列に結果を格納します。たとえば、fetchAssoc ループでは次のようになります。

$row->sizes = array();
$products[$row->product_id] = $row;

結果から製品 ID を抽出します。

$productIds = (',', array_keys($products));

関連するサイズを取得します。

select product_id, size
from products_sizes
where product_id in ($productIds)
order by product_id, size

サイズをループでリンクする

$products[$row->product_id]->sizes[] = $row->size;

次のサンプルデータが与えられた場合

| product_id |   name | category | sizes |
|------------|--------|----------|-------|
|          1 | shoes1 |    shoes |   8,9 |
|          2 | shirt1 |   shirts | 10,11 |
|          3 | shoes2 |    shoes |  9,10 |
|          4 | shoes3 |    shoes | 10,11 |
|          5 | shoes4 |    shoes | 10,12 |

を使用するLIMIT 2 OFFSET 0と、結果は次のようになります。

1.

| product_id |   name | category | size |
|------------|--------|----------|------|
|          3 | shoes2 |    shoes |    9 |
|          3 | shoes2 |    shoes |   10 |
|          4 | shoes3 |    shoes |   10 |
|          4 | shoes3 |    shoes |   11 |

2.

| product_id |   name | category | sizes |
|------------|--------|----------|-------|
|          3 | shoes2 |    shoes |  9,10 |
|          4 | shoes3 |    shoes | 10,11 |

3.

| product_id |   name | category |
|------------|--------|----------|
|          3 | shoes2 |    shoes |
|          4 | shoes3 |    shoes |

| product_id | size |
|------------|------|
|          3 |    9 |
|          3 |   10 |
|          4 |   10 |
|          4 |   11 |

デモ:

于 2016-11-05T22:06:03.723 に答える
0

あなたの最終的な質問は完全に正しかったです。サブクエリ内で制限を使用するだけで、製品の数がバインドされます。

于 2013-12-02T09:55:41.310 に答える
-1
SELECT *
FROM products AS p
LEFT JOIN products_sizes AS s ON p.product_id = s.product_id
WHERE p.product_id IN (SELECT product_id FROM products_sizes WHERE size = 10)
LIMIT 15

編集(説明):

私はそれについて考えていて、あなたもその理由を知りたいかもしれないことに気づきました:p

あなたは特定の基準を満たす製品に興味があるので、それが選択する主要なテーブルです。

その商品で利用できるサイズを知りたい場合は、サイズを商品に結合してください。

あなたは特定のサイズの製品にのみ興味があります。サブクエリを実行して、そのサイズの製品を見つけます。それらの製品のみを表示します。

于 2013-01-20T17:02:48.500 に答える