Given this table structure and example data (t3 should not be used in the query, it is only here to show the relation between t1 and t2):
t1 t2 t3
-------------- ----------------- --------------------------------
| id | value | | t1key | t3key | | id | value |
| 1 | 2008 | | 3 | 1 | | 1 | "New intel cpu in 2010" |
| 2 | 2009 | | 4 | 1 | | 2 | "New amd cpu in 2008" |
| 3 | 2010 | | 6 | 1 | | | ... |
| 4 | intel | | 1 | 2 | --------------------------------
| 5 | amd | | 5 | 2 |
| 6 | cpu | | 6 | 2 |
| | ... | | | ... |
-------------- -----------------
How would you build a SQL query that would satisfy the following:
Given the input for t1.id is the set {6} returns t1.id set {3,4,6,1,5}
Given the input for t1.id is the set {6,4} returns t1.id set {3,4,6}
Given the input for t1.id is the set {5,4} returns t1.id set {}
and doesn't kill performance when the tables are bigger...?
Here is my brilliant contribution (at least let's assume it's brilliant for now:)
The
IN (6,4)
part is really self explanatory. In thecnt >=2
2 is the number ofid
-s in theIN
clause. For example: you're usingIN (6)
then you should usecnt >=1
.I'm not sure
>
is needed at all, but I am lazy enogh not to create a larger dataset to test on :)Starting on t1 (the keyword), you get all the t3 (expressions) which contain "cpu" (or whatever). You don't need to join t3 directly, you don't need any data from there. Joining t2 a second time you get all other keywords which are contained in the found expressions. You only need to return the t1key's of them.
Correction: If you don't want subqueries, you could create a join for each keyword to search for:
He there, Are you sure you have chosen the right table structure? It doesn't seem to be normalized - though I don't know exactly what entity each table could represent.
Its important to keep your database design at least in the third normal form (see Wikipedia article
Your queries will be much more natural and easily formulated
You would need to add more "intersect" clauses depending on how many items are in your input set.
Tested on SQL Server.
It's not very clear what you want.
I will call table t1
word
, call table t3phrase
and call table t2word is in phrase
.Then I guess you want to find all word.ids that are in a same phrase as a specific set of word.ids. Is that correct?
CORRECTION
Reading Joe's comment and re-reading the question details, I guess you want to find all words that appear in same phrase with ALL words in your specified list.
This looks like a relational division problem:
2nd solution:
3rd solution:
Note: The first (with
NON EXISTS
) solution has a great difference with the other two:If you try it with a list that its members do not appear in table t2, say
(2)
or(2,7)
, it will show ALL t1key's from t2.The 2nd and 3rd solutions will show NO keys at all in such a case.