2

SQLを実行してからしばらく経ちましたが、この問題に簡単な解決策があるかどうかはわかりません。また、私は少し初心者です。

ユーザーがタグを使用して画像を検索し、追加のタグをクリックして検索を絞り込み、結果の数を減らすことができる画像ギャラリーを作成しようとしていますが、関連するクエリに大きな問題があります。

これは私の現在のデータベース構造の簡略版です。

(追加の多対多リンクテーブルを含む2つのテーブル)

CREATE TABLE images(
   image_id INT(12) AUTO_INCREMENT,
   image_name VARCHAR(128),
   PRIMARY KEY(image_id)
)ENGINE= INNODB;

CREATE TABLE tags(
   tag_name VARCHAR(64) NOT NULL,
   PRIMARY KEY(tag_name)
)ENGINE= INNODB;

CREATE TABLE images_tags_link(
   image_id_fk INT(12),
   tag_name_fk VARCHAR(64) NOT NULL,
   PRIMARY KEY(image_id_fk,tag_name_fk),
   FOREIGN KEY(image_id_fk) REFERENCES images(image_id),
   FOREIGN KEY(tag_name_fk) REFERENCES tags(tag_name)
)ENGINE= INNODB;

サンプルデータ:

 ===images===
 ___________________________       
| image_id |  image_name    |     
|----------|----------------|     
|     1    |  image_001.jpg |     
|     2    |  image_002.jpg |     
|     3    |  image_003.png |     
|     4    |  image_004.jpg |     
|     5    |  image_005.gif |     
 ---------------------------                                     
 ===tags===                                 
 _______________
|    tag_name   |
|---------------|
| Landscape     |
| Portrait      |
| Illustration  |
| Photo         |
| Red           |
| Blue          |
| Character     |
| Structure     |
 ---------------
===images_tags_link===
 ________________________________
| image_id_fk | tag_name_ fk     |
|-------------|------------------|
|      1      |    Landscape     |
|      1      |    Illustration  |
|      1      |    Blue          |
|      2      |    Blue          |
|      2      |    structure     |
|      2      |    Landscape     |
|      3      |    Illustration  |
|      4      |    Red           |
|      4      |    Portrait      |
|      4      |    Character     |
|      5      |    Blue          |
|      5      |    Photo         |
 --------------------------------

私の問題は次のクエリにあります:

すべてのユーザーがタグをリストしたIMAGESテーブルからすべての「image_names」を選択できる単一のクエリを探しています。たとえば、ユーザーは「Blue」および「Landscape」タグを検索して、image_names「image_001」のみを出力する必要があります。 .jpg'AND'image_002.jpg'。

===入力===

ユーザーが選択したタグ:('青'、'風景')

===出力===

リストされているすべてのタグを持つimage_names:('image_001.jpg'、'image_002.jpg')

前もって感謝します。

4

4 に答える 4

3

これはRelation Divisionと呼ばれるもので、これを行う 1 つの方法を次に示します。

SELECT i.*
FROM Images i 
INNER JOIN
(
   SELECT image_id_fk
   FROM images_tags_link
   WHERE tag_name_fk IN ('Blue' , 'Landscape')
   GROUP BY image_id_fk 
   HAVING COUNT(DISTINCT tag_name_fk) = 2
) t ON i.image_id = t.image_id_fk;

SQL フィドルのデモ

これにより、次のことが得られます。

| IMAGE_ID |    IMAGE_NAME |
----------------------------
|        1 | image_001.jpg |
|        2 | image_002.jpg |

このクエリの背後にある考え方は次のとおりです。

   GROUP BY image_id_fk 
   HAVING COUNT(DISTINCT tag_name_fk) = 2

サブクエリでは、画像に両方のタグがあることが保証されます。タグが 1 つしかない場合はCOUNT0 になるため、削除されます。

于 2013-02-04T09:12:42.943 に答える
1

それを行う2つの簡単な方法。

必要な列、可能なタグの数などに応じて、次のいずれか。

SELECT *
FROM images
INNER JOIN images_tags_link a ON images.image_id = a.image_id_fk AND a.tag_name_fk = 'Blue'
INNER JOIN images_tags_link b ON images.image_id = b.image_id_fk AND b.tag_name_fk = 'Landscape'


SELECT images.image_id, images.image_name, COUNT(*) AS tag_count
FROM images
INNER JOIN images_tags_link a ON images.image_id = a.image_id_fk 
WHERE a.tag_name_fk IN ('Blue', 'Landscape')
GROUP BY images.image_id, images.image_name
HAVING tag_count = 2
于 2013-02-04T09:16:15.953 に答える
1

EXISTS を使用した別の例を次に示します。

SELECT *
FROM Images I
WHERE EXISTS (
   SELECT image_id_fk
   FROM Images_Tags_Link I2 
   WHERE I2.image_id_fk = I.Image_Id
      AND tag_name_fk IN ('Blue' , 'Landscape')
   GROUP BY I2.image_id_fk
   HAVING COUNT(DISTINCT I2.tag_name_fk) > 1)

そして、INを使用するもの:

SELECT *
FROM Images I
WHERE Image_Id IN (
   SELECT image_id_fk
   FROM Images_Tags_Link I2 
   WHERE I2.image_id_fk = I.Image_Id
      AND tag_name_fk IN ('Blue' , 'Landscape')
   GROUP BY I2.image_id_fk
   HAVING COUNT(DISTINCT I2.tag_name_fk) > 1)

幸運を。

于 2013-02-04T09:18:02.523 に答える
0

この簡単な方法を試してください


('Blue','Landscape') に tag_name_fk がある
images_tags_link
から
image_name を選択 します。

于 2013-02-04T09:36:06.697 に答える