0

私は2つのテーブルを持っています:

製品:

+-------------------------------------------------+
|   id   |    name   |   category     |   price   |
+-------------------------------------- ----------+
|    1   |    item1  |      1         |   0.99    |
|    2   |    item2  |      2         |   1.99    |
|    3   |    item3  |      3         |   2.95    |
|    4   |    item4  |      4         |   2.50    |
+-------------------------------------------------+

画像:

+--------------------------------------------------+
|   id   |    file_name    |   p_id   |   priority |
+-------------------------------------- -----------+
|    1   |      image1     |     1    |      0     |
|    2   |      image2     |     1    |      1     |
|    3   |      image3     |     2    |      2     |
|    4   |      image4     |     3    |      2     |
|    5   |      image5     |     3    |      3     |
|    11  |      image6     |     3    |      5     |
|    16  |      image7     |     4    |      1     |
|    19  |      image8     |     4    |      7     |
+--------------------------------------------------+

すべての製品情報と、製品の画像のファイル名を取得する必要があります。商品には複数の画像を含めることができることに注意してください。優先度の低いものを希望します。また、特定のカテゴリに属する​​製品の結果のみが必要です。

たとえば、カテゴリ {1,2,3} の製品の情報が必要だとすると、クエリを実行すると、次の結果が返されます。

+-----------------------------------------------------------------+
|   id   |    name   |   category     |   price   |   file_name   |
+-------------------------------------- ----------+---------------+
|    1   |    item1  |      1         |   0.99    |     image1    |
|    2   |    item2  |      2         |   1.99    |     image3    |
|    3   |    item3  |      3         |   2.95    |     image4    |
+-------------------------------------------------+---------------+

いくつかの異なる結合ステートメントを作成しようとしましたが、どれも機能しません。私は SQL に関してはまったくの初心者なので、驚くことではありません。

どんな助けでも大歓迎です!

4

3 に答える 3

4

ステップバイステップのチュートリアルを追加します。最初に結合を正しく取得し、次にいくつかの条件を追加してカテゴリをフィルタリングし、最後にグループ化してサブセレクトで having 句を使用します。コードで最後の選択を使用する必要があります。これをmysqlインスタンスでもテストしましたが、動作します。他の複雑なものが必要な場合に備えて、group by を使用しています。例があると良いです。構文は ansii sql です。mysql だけでなく、すべてのデータベースで動作するはずです。

-- get everything by joining
select p.*, i.file_name
from products p 
join image i on (p.id = i.p_id)



/* get everything by joining 
 *  + filter by category
 */
select p.*, i.file_name
from products p 
join image i on (p.id = i.p_id)
where p.category in (1,2,3)


/* get everything by joining 
* + filter by category
* + image is the one with the lowest priority
* note: selecting the priority is not necessary 
* but it's good for demonstration purposes
*/
select p.*, i.file_name, i.priority
from products p 
join image i on (p.id = i.p_id)
where p.category in (1,2,3)
group by p.id 
having i.priority = (select min(priority) from image where p_id = p.id)
于 2012-05-19T17:01:29.643 に答える
2

これが答えです:

select a.id, a.name, a.category, a.price, b.filename as file_name 
from products a left join (
    select i.p_id, i.filename from (select id, min(priority) as min_p 
    from images group by p_id) q 
    left join images i on q.id = i.id
) b on a.id = b.p_id 
where a.category in (1, 2, 3);

説明:

まず、次のクエリから、優先度が最も低い各製品のセットを取得する必要があります。

select id, min(priority) as min_p from images group by p_id;

結果は次のようになります。

+----+----------+
| id | lowest_p |
+----+----------+
|  1 |        0 |
|  2 |        2 |
|  3 |        2 |
|  4 |        1 |
+----+----------+
4 rows in set (0.00 sec)

次のステップは、外部結合を取得することです。この場合、(好みに応じて任意に) 左結合を選択します。

select i.p_id, i.filename from (select id, min(priority) as min_p 
from images group by p_id) q left join images i on q.id = i.id;

このクエリは、要するに必要なものを生成します。

+------+----------+
| p_id | filename |
+------+----------+
|    1 | image1   |
|    2 | image3   |
|    3 | image4   |
|    4 | image7   |
+------+----------+
4 rows in set (0.00 sec)

これを装飾する必要があるだけです。ここでも左結合を使用します。

select a.id, a.name, a.category, a.price, b.filename as file_name 
from products a left join (
    select i.p_id, i.filename from (select id, min(priority) as min_p 
    from images group by p_id) q 
    left join images i on q.id = i.id
) b on a.id = b.p_id 
where a.category in (1, 2, 3);

そして、あなたはあなたが望むものを手に入れるでしょう:

+------+-------+----------+-------+-----------+
| id   | name  | category | price | file_name |
+------+-------+----------+-------+-----------+
|    1 | item1 |        1 |  0.99 | image1    |
|    2 | item2 |        2 |  1.99 | image3    |
|    3 | item3 |        3 |  2.95 | image4    |
+------+-------+----------+-------+-----------+
3 rows in set (0.00 sec)

画像のない商品がある場合の予想に応じて、左側の接合部の右側に商品を配置することもできます。上記のクエリは、file_name フィールドを「null」として、上記のようにビューを表示します。

逆に、左結合の右側に商品を入れると何も表示されません。

于 2012-05-19T17:13:32.627 に答える
0

sarwar026の答えに基づいて構築...

SELECT p.id, name, priority, price, file_name
FROM Products p, Images i
WHERE p.id = i.p_id
  AND i.priority = (SELECT MIN(priority) FROM Images ii WHERE ii.p_id = p.id)
  AND p.category IN (1,2,3)

(テーブルのコピーを使用してmysqlデータベースでテスト済み)

于 2012-05-19T17:03:12.343 に答える