1

I want to be able to query for multiple statements when I have a table that connects the id's from two other tables.

My three tables

destination:
id_destination, name_destination

keyword:
id_keyword, name_keyword

destination_keyword:
id_keyword, id_destination

Where the last one connects ids from the destination- and the keyword table, in order to associate destination with keywords.

A query to get the destination based on keyword would then look like

SELECT destination.name_destination FROM destination
            NATURAL JOIN destination_keyword 
            NATURAL JOIN keyword
            WHERE keyword.name_keyword like _keyword_

Is it possible to query for multiple keywords, let's say I wanted to get the destinations that matches all or some of the keywords in the list sunny, ocean, fishing and order by number of matches. How would I move forward? Should I restructure my tables? I am sort of new to SQL and would very much like some input.

2
  • Are name_keyword values single words like "sunny"? Commented May 6, 2013 at 19:05
  • They are single words, yes. Commented May 6, 2013 at 19:18

3 Answers 3

1

Order your table joins starting with keyword and use a count on the number of time the destination is joined:

select
    d.id_destination,
    d.name_destination,
    count(d.id_destination) as matches
from keyword k
join destination_keyword dk on dk.keyword = k.keyword
join destination d on d.id_destination = dk.id_destination
where name_keyword in ('sunny', 'ocean', 'fishing')
group by 1, 2
order by 3 desc

This query assumes that name_keyword values are single words like "sunny".


Using natural joins is not a good idea, because if the table structures change such that two naturally joined tables get altered to have columns the same name added, suddenly your query will stop working. Also by explicitly declaring the join condition, readers of your code will immediately understand how the tables are jones, and can modify it to add non-key conditions as required.

Requiring that only key columns share the same name is also restrictive, because it requires unnatural column names like "name_keyword" instead of simply "name" - the suffix "_keyword" is redundant and adds no value and exists only because your have to have it because you are using natural joins.

Natural joins save hardly any typing (and often cause more typing over all) and impose limitations on join types and names and are brittle.

They are to be avoided.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, that works great. I was unsure considering I'm fetching from several lines and comparing them. Is it possible to display the separate matches as well? Also selecting the keywords that matches, like 'sunny', 'ocean'. - And name_keyword is a single word, yes.
0

You can try something like the following:

SELECT dest.name_destination, count(*) FROM destination dest, destination_keyword dest_key, keyword key 
WHERE key.id_keyword = dest_key.id_keyword
AND dest_key.id_destination = dest.id_destination
AND key.name_keyword IN ('sunny', 'ocean', 'fishing')
GROUP BY dest.name_destination
ORDER BY count(*), dest.name_destination

Haven't tested it, but if it is not correct it should show you the way to accomplish it.

2 Comments

I think the OP wants to do a LIKE match. So your solution will not work as LIKE does not work with IN.
@NabheetSandhu Well, checking the answer he marked as correct seems he didn't need the LIKE.
0

You can do multiple LIKE statements:

Column LIKE 'value1' OR Column LIKE 'value2' OR ...

Or you could do a regular expression match:

Column LIKE 'something|somtthing|whatever'

The trick to ordering by number of matches has to do with understanding the GROUP BY clause and the ORDER BY clause. You either want one count for everything, or you want one count per something. So for the first case you just use the COUNT function by itself. In the second case you use the GROUP BY clause to "group" somethings/categories that you want counted. ORDER BY should be pretty straight forward.

I think based on the information you have provided your table structure is fine.

Hope this helps.

DISCLAIMER: My syntax isn't accurate.

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.