2

I need to be able to have an SQL query that searches my database using a simple search. Here is what my tables look like right now:

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

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

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

How would I go about doing this? Here are some SQL queries that I have tried, but my issue is that it is returning a lot of data. For instance, if I search for an artist like Snoop Dogg, it is returning a row for each album and song that he has even if they don't contain his name.

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

Edit:

Here is a sample database;

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

So I want a search for "snoop" to return just the artist "Snoop Dogg". But then a search like "Linkin" to return the artist and the song.

6
  • Table songs dont have artistID? Commented Mar 21, 2012 at 23:51
  • @safarov They don't, but I could add it. Commented Mar 21, 2012 at 23:53
  • if no then how you detect which song belongs to artist Commented Mar 21, 2012 at 23:54
  • First, joins are missing. Second, what do you want to see if you type in "snoop" if not his songs? Commented Mar 21, 2012 at 23:57
  • @safarov Well each song is linked to an album and that is linked to an artist. Commented Mar 21, 2012 at 23:58

5 Answers 5

5

This query will retrieve matching artists, songs and albums. First column gives a clue about origin of the data, second is id and the last is the name.

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%'
Sign up to request clarification or add additional context in comments.

Comments

5

The following uses UNION, thus avoids JOINs:

(
    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%'
)

3 Comments

I got this error when trying this: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE artists.name LIKE '%snoop' ) UNION ( SELECT ' at line 6
And also, how does type differentiate from OriginatingTable in Nikola's answer?
@Flipper: I missed FROM statement, this probably caused an error for you :) I looked at Nikola's answer: his originating table does what my type does, there are not many differences however. There is one inconsistency (the column is called OriginatingTable, but contains a string that is different than table name, is not lowercase), plus my solution allows you to modify partial queries thanks to brackets. If you wish to eg. add ORDER BY etc. within his solution, then add brackets like in my answer. Anyway, as I said, his answer is very similar to mine, but he was 1.5 minute faster ;)
3

You need to join all your data together so it becomes one big data set that will allow you to query against all fields at once. To do this you want to use a left join which is the most optimal for this scenario.

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 could also be used, but this may not give you the results you want. A left join will give you a row for every song that matches the artist, album, or song. A union will give you a row for each song where where it matches the song name, a row for each album where it matches the album name, and a row for each artist where is matches the artist name.

Comments

0

You should select from each table and return and union of the results, but remember that all the select must return the same number and kind of columns.

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%'

This way you avoid getting a combination of all the tables, and you also have all the available info in each row.

Comments

-1

This query search on artist name, song name and album name

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%'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.