2012-03-21 84 views
2

我需要能夠使用簡單搜索來搜索我的數據庫的SQL查詢。這裏是我現在的表格:搜索多個表(SQL)

Table artists 
-------------- 
id 
name 

Table albums 
------------- 
id 
artistID 
name 

Table songs 
------------ 
id 
albumID 
name 

我該如何去做這件事?以下是我嘗試過的一些SQL查詢,但我的問題是它返回了很多數據。例如,如果我搜索像Snoop Dogg這樣的藝術家,那麼即使他們不包含他的名字,它也會爲每張專輯和歌曲返回一行。

SELECT * FROM artist,album,songs WHERE artist.name LIKE '%snoop%' OR albums.name LIKE '%snoop%' OR songs.name LIKE '%snoop%'; 

編輯:

這裏是一個示例數據庫;

artists 
----------- 
1 | Snoop Dogg 
2 | Linkin Park 

albums 
-------- 
1 | artist=1 | Boom 
2 | artist=2 | ThisIsIt 

songs 
-------- 
1 | album=1 | First 
2 | album=2 | Second Linkin 
3 | album=2 | Third 
4 | album=1 | Fourth 

所以我想爲「窺探」的搜索只返回藝術家「史努比狗狗」。但隨後像「Linkin」這樣的搜索將返回藝術家和歌曲。

+0

表歌沒有'artistID'? – safarov 2012-03-21 23:51:35

+0

@safarov他們沒有,但我可以添加它。 – Flipper 2012-03-21 23:53:06

+0

如果沒有,那麼你如何檢測哪首歌屬於藝術家 – safarov 2012-03-21 23:54:02

回答

3

這個查詢將檢索匹配的藝術家,歌曲和專輯查詢搜索。第一列給出了關於數據來源的線索,第二列是id,最後一個是名字。

select 'Artists' OriginatingTable, id, name 
    from artists 
where name like '%snoop%' 
union all 
select 'Albums', id, name 
    from albums 
where name like '%snoop%' 
union all 
select 'Songs', id, name 
    from songs 
where name like '%snoop%' 
+0

這工作完美!謝謝! – Flipper 2012-03-22 01:22:31

2

您需要將所有數據連接在一起,以便它成爲一個大數據集,允許您一次查詢所有字段。要做到這一點,你想使用left join這是最適合這種情況。

SELECT * 
FROM songs 
LEFT JOIN albums 
ON songs.albumID = albums.id 
LEFT JOIN artists 
ON albums.artistID = artists.id 
WHERE artist.name LIKE '%snoop%' 
OR albums.name LIKE '%snoop%' 
OR songs.name LIKE '%snoop%'; 

A union也可以使用,但這可能不會給你你想要的結果。左連接會爲每首與藝術家,專輯或歌曲匹配的歌曲添加一行。工會會爲每首歌曲提供一行,使其與歌曲名稱匹配,每張專輯的行與專輯名稱匹配,並且每位藝術家的行與藝術家姓名相匹配。

-1

這對歌手名,歌曲名和專輯名稱

SELECT artist.name,albums.name,songs.name 
FROM songs 
LEFT JOIN album ON album.id = song.albumID 
LEFT JOIN artists ON album.artistID = artists.id 
WHERE 
artist.name LIKE '%snoop%' OR albums.name LIKE '%snoop%' OR songs.name LIKE '%snoop%' 
4

下使用UNION,從而避免JOIN S:

(
    SELECT 
     'artist' as `type`, 
     `artists`.`id` as `id`, 
     `artists`.`name` as `name` 
    FROM `artists` 
    WHERE 
     `artists`.`name` LIKE '%snoop%' 
) 
UNION 
(
    SELECT 
     'album' as `type`, 
     `albums`.`id` as `id`, 
     `albums`.`name` as `name` 
    FROM `albums` 
    WHERE 
     `albums`.`name` LIKE '%snoop%' 
) 
UNION 
(
    SELECT 
     'song' as `type`, 
     `songs`.`id` as `id`, 
     `songs`.`name` as `name` 
    FROM `songs` 
    WHERE 
     `songs`.`name` LIKE '%snoop%' 
) 
+0

有類型的列也在選擇是一個非常好的想法.. – 2012-03-22 00:27:55

+0

當我嘗試這個時得到了這個錯誤:#1064 - 你的SQL語法錯誤;檢查與您的MySQL服務器版本相對應的手冊,以找到在'WHERE'artists'附近使用的正確語法。'name' LIKE'%snoop')第6行的UNION(SELECT) – Flipper 2012-03-22 01:05:15

+0

此外,在Nikola的答案中,OriginatingTable中的類型如何區分? – Flipper 2012-03-22 01:05:39

0

你應該從每個表中選擇和結果的返回和工會,但請記住,所有的選擇必須返回相同的號碼,種類的列。

SELECT 'Artist' as kind, id as artistId, name, null as albumId, null as SongId 
FROM artist WHERE artist.name LIKE '%snoop%' 
union 
SELECT 'Album', artistId, name, id, null FROM album WHERE albums.name LIKE '%snoop%' 
union 
SELECT 'Song', albums.artistId, songs.name, songs.albumId, songs.id 
FROM songs inner join albums on songs.albumId = albums.id 
WHERE songs.name LIKE '%snoop%' 

這樣會避免所有表的組合,你也有各行中的所有可用信息。