簡體   English   中英

PHP MYSQL查詢,使用來自多個表的數據搜索多個字段/列

[英]PHP MYSQL query, searching multiple fields/columns using data from multiple tables

很長一段時間潛伏在這里,多年來一直在使用這個網站的建議,現在我有一個問題,我找不到答案 - 我確信解決方案很簡單!

我正在為音樂曲目建立一個標記系統。 我有三張桌子

曲目

---------------
| id | name   |
---------------
| 1  | Track1 |
| 2  | Track2 |
---------------

Taglinks

--------------------------
| id | tag_id | track_id |
--------------------------
| 1  | 1      | 1        | 
| 2  | 2      | 1        | 
| 3  | 2      | 2        |
--------------------------

標簽

-------------------------
| id | tag      | type  |
-------------------------
| 1  | acoustic | genre | 
| 2  | anger    | mood  |
-------------------------

我希望能夠獲得曲目的曲目名稱,例如,標簽:聲音,類型:流派和標簽:憤怒,類型:心情。 所以在這種情況下我想要跟蹤1,因為它有兩個標簽。

我當前的查詢是

SELECT tracks.name 
FROM tracks
JOIN taglinks ON tracks.id=taglinks.track_id
JOIN tags ON (tags.type='genre' AND tags.tag='acoustic') AND (tags.type='mood' AND tags.tag='anger')
WHERE taglinks.tag_id=tags.id;

如果我刪除第二個JOIN中的AND部分,那么我將返回任何內容,然后我將所有軌道標記為預期的聲音,如果我將其更改為OR,我將再次按預期獲得兩個軌道。

我如何做一個AND雖然只返回那些同時具有這些標簽和類型的曲目?

提前致謝

編輯:

只是為了澄清我的追求。 我希望能夠檢索同時具有Acoustic和Anger作為標簽的軌道,但僅當這些標簽也與給定類型匹配時才能檢索。

這是因為后來我可能會有一個名為jazz的類型為genre的標簽,以及一個名為jazz的帶有類型樣式的標簽,我需要能夠確保選擇正確的標簽類型以及標簽本身。

這是我正在使用的sqlfiddle的鏈接 - http://sqlfiddle.com/#!2/aad82/3

到目前為止,吉爾斯的答案似乎是一個很好的解決方案!

這應該沒問題

select
t.name
from
tracks as t 
inner join taglinks as tl on t.id = tl.track_id
inner join tags as tg on tl.tag_id = tg.id
where
tg.tag = 'acoustic' and
tg.type = 'genre' and 
tg.tag = 'anger' and
tg.type = 'mood';

注意:我使用as identifier name as identifier ,因為它可以節省在任何地方寫表名。 你不必。

編輯

我可能會誤解你的問題,所以這個也可能有所幫助:

select
t.name
from
tracks as t 
inner join taglinks as tl on t.id = tl.track_id
inner join tags as tg on tl.tag_id = tg.id
where
(tg.tag = 'acoustic' and
tg.type = 'genre') or 
(tg.tag = 'anger' and
tg.type = 'mood');

這將返回具有正確類型AND標記的結果,但不必擁有所有這些結果。

問題是軌道應該有2個標簽等於要求的值,所有發布的請求在那種情況下都不起作用。 必須使用INTERSECT sql命令,但這個命令在mysql中不可用。

這樣的東西應該工作:

SELECT tracks.id, tracks.name
FROM  `taglinks` 
LEFT JOIN tags ON tags.id = taglinks.tag_id
LEFT JOIN tracks ON tracks.id = taglinks.track_id
WHERE (
tag =  'accoustic'
AND `type` =  'genre'
)
OR (
tag =  'anger'
AND `type`=  'mood'
)
GROUP BY track_id
HAVING COUNT( * ) =2
  • 我選擇了至少匹配一個標簽的所有行
  • 我計算與GROUP BY匹配的tage數。
  • 如果我搜索兩個參數(這里accoustic = 'genre'anger = 'mood'並找到該行的2行,那么它匹配2個條件並保持最終結果
  • 只記得用我們想要搜索的標簽數量來改變HAVING COUNT( * ) =2
SELECT * FROM tracks tracks
INNER JOIN
(SELECT taglinks.track_id, COUNT(*) as cnt
FROM tags tags
INNER JOIN taglinks taglinks ON taglinks.tag_id = tags.id
WHERE
    (tags.tag='ac' AND tags.type='ge')
    OR (tags.tag='an' AND tags.type='mo')
GROUP BY taglinks.track_id
)AS track_match
    ON track_match.track_id = tracks.id AND track_match.cnt = 2

您需要替換“track_match.cnt = 2”2 =要匹配的條件數

此解決方案提供了一些靈活性:您還可以在滿足最少條件的情況下使用軌道。

例如,您可以在此添加track_match.cnt> = 1以及ORDER BY track_match.cnt DESC

獲取按匹配條件數排序的軌道列表。

暫無
暫無

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

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