簡體   English   中英

MySQL:如果聯接表中的列包含x,則選擇具有相同ID的所有行

[英]MySQL: Select all rows with the same ID, if a column from a joined table contains x

(為清楚起見,此處提供了一個極為簡化的示例。)

我在一個數據庫中有一個多對多關系(帶有Doctrine2 / Symfony2實體的MySQL,但我想知道普通SQL中的答案),並且在它們之間有一個簡單的2列“聯接表”:

項目
ID ITEMNAME
1 只貓
2只 老鼠

標簽
id 標記名
1 捕食者
2 獵物
3 Likes奶酪
4 飛行

item_tag
item_id tag_id
1 1
1 3
2 2
2 3

為此的標准聯接查詢:

SELECT itemname, tagname FROM item
JOIN item_tag ON  item_tag.item_id = item.id
JOIN tag ON item_tag.tag_id = tag.id

給我我感興趣的所有數據,某些行當然是兩倍:

項目
項目名稱 標記名
捕食者
喜歡奶酪
老鼠 獵物
老鼠 喜歡奶酪

現在,我需要使用簡單的WHERE語句對此進行過濾,因此我需要添加以下內容:

WHERE tagname = 'prey'

但這當然只返回一行。 我需要獲取所有帶有“獵物標簽”的項目的所有行-因此鼠標項目的所有行。 鼠標喜歡奶酪的事實是您尋找獵物時要知道的一個非常重要的細節!

重點當然是要輸入針對特定標簽名稱的搜索查詢(不事先知道商品名稱),但是一旦它返回一組商品,我也希望查看該商品中的所有其他標簽組。

一個查詢是否可能做到這一點,還是我將不得不重新查詢以獲取其余的關聯標簽?

您可以像這樣從每個獵物獲取item_id:

SELECT it.item_id
FROM item_tag it
JOIN tag t ON t.id = it.tag_id AND t.tagname = 'prey';

然后,您可以將其用作原始查詢的`WHERE子句中的子查詢,以獲取這些項目的所有行:

SELECT i.itemname, t.tagname
FROM item i
JOIN item_tag it ON it.item_id = i.id
JOIN tag t ON t.id = it.tag_id
WHERE i.id IN(
   SELECT it.item_id
   FROM item_tag it
   JOIN tag t ON t.id = it.tag_id AND t.tagname = 'prey');

這是一個SQL Fiddle示例。

以為我還會包括我的Symfony2 / Doctrine解決方案,該解決方案基於McAdam331對SQL的回答。

我在項目存儲庫中使用了第二個查詢構建器實例作為子查詢。 當然,您只需要使用與主查詢構建器中使用的索引不同的索引即可。

$qb = $this->createQueryBuilder('i');
$sub = $this->createQueryBuilder('subi');

$search = $qb->expr()->orX(
    $qb->expr()->like('i.name', ':s'),
    $qb->expr()->in('i.id', 
        $sub->select('subi.id')
        ->join('subi.tags', 'subt')
        ->where($sub->expr()->like('subt.tagname',':s'))->getDQL()
    ),
    ... // various other search expressions are included in the OR clause
)

$qb->select('i','t')->join->('i.tags','t') // etcetera
   ->where($search)
   ->setParameter('s', "%".$searchString."%")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM