MySQL query inquery
- ScottG
- Proficient


- Joined: Jul 06, 2010
- Posts: 266
- Status: Offline
OK so I've been working on an image archive system (redevelopment) and the issue I'm having is that people are having search issues. Now there are some things about this one it that the keywords that are attached have to be added into the file's db record and not an id relating to the keyword (Not my style but this is how it has to be). The reasoning behind this it that if the keyword gets deleted they still want to be able to find the file with that keyword (again not my style I don't delete anything from the database).
So here is an example table dumbed down to the keywords column
So If I ran a query like
I would get all three of the results in the example table above when all I would want is record 3 and 4. The keywords column is a text column. so doing a sql query like
would return no results since it is in a text based array format. What I would need to do is have a query find exactly te in the results. I could do a query to find the first set then process the keywords in php and match against the search to find the exact match but would prefer not to have php process it and have Mysql return the correct result set.
So it anyone has any thoughts on this please let me know, and feel free to ask any questions you may have
So here is an example table dumbed down to the keywords column
MYSQL Code: [ Select ]
Files Table
+----------+----------------------------------------+
| id | keywords |
+----------+----------------------------------------+
| 1 | ["Test","test 2","test 3"] |
| 2 | ["team","tetris"] |
| 3 | ["Test", "te"] |
| 4 | ["te"] |
+----------+----------------------------------------+
| id | keywords |
+----------+----------------------------------------+
| 1 | ["Test","test 2","test 3"] |
| 2 | ["team","tetris"] |
| 3 | ["Test", "te"] |
| 4 | ["te"] |
- Files Table
- +----------+----------------------------------------+
- | id | keywords |
- +----------+----------------------------------------+
- | 1 | ["Test","test 2","test 3"] |
- | 2 | ["team","tetris"] |
- | 3 | ["Test", "te"] |
- | 4 | ["te"] |
So If I ran a query like
MYSQL Code: [ Select ]
SELECT `files`.`id`
FROM `files`
WHERE `files`.`keywords` LIKE '%te%'
FROM `files`
WHERE `files`.`keywords` LIKE '%te%'
- SELECT `files`.`id`
- FROM `files`
- WHERE `files`.`keywords` LIKE '%te%'
I would get all three of the results in the example table above when all I would want is record 3 and 4. The keywords column is a text column. so doing a sql query like
MYSQL Code: [ Select ]
SELECT `files`.`id`
FROM `files`
WHERE `files`.`keywords` LIKE 'te'
OR like
SELECT `files`.`id`
FROM `files`
WHERE `files`.`keywords` = 'te'
FROM `files`
WHERE `files`.`keywords` LIKE 'te'
OR like
SELECT `files`.`id`
FROM `files`
WHERE `files`.`keywords` = 'te'
- SELECT `files`.`id`
- FROM `files`
- WHERE `files`.`keywords` LIKE 'te'
- OR like
- SELECT `files`.`id`
- FROM `files`
- WHERE `files`.`keywords` = 'te'
would return no results since it is in a text based array format. What I would need to do is have a query find exactly te in the results. I could do a query to find the first set then process the keywords in php and match against the search to find the exact match but would prefer not to have php process it and have Mysql return the correct result set.
So it anyone has any thoughts on this please let me know, and feel free to ask any questions you may have
- Anonymous
- Bot


- Joined: 25 Feb 2008
- Posts: ?
- Loc: Ozzuland
- Status: Online
April 10th, 2012, 11:42 am
- ScottG
- Proficient


- Joined: Jul 06, 2010
- Posts: 266
- Status: Offline
OK. So after much deliberation with the client and several failed MySQL attempts I am going to the continue to have the keywords attached to the file as well as go with how I do database structure and use a many to one relationship table. This will make it able to have an exact match for a search as well as using said attached keywords to just do a wild card search so I do not have to join to the relationship table when doing a wild card search and maintain backwards compatibility.
- Bigwebmaster
- Site Admin


- Joined: Dec 20, 2002
- Posts: 8925
- Loc: Seattle, WA & Phoenix, AZ
- Status: Online
Hi Scott,
Are you restricted at only using that database structure? The reason I ask is that I think the ideal way to do this would be to create a keywords table and associate the keywords with the file ID. So you would still have your files table, but you would no longer put keywords in them. Instead you would create a new table called keywords with a structure similar to:
So basically you would list every keyword individually and associate it with the file_id that has it. Then when you do a MySQL query it will let you know exactly what file ids have an exact match on a keyword. For example:
That would return file id 3 and 4.
You could also go one step further to prevent keywords from being duplicated over and over in this table and make another keyword table that lists each unique keyword and assigns each one a keyword_id. Then with the table above you would put the keyword_id and the file_id.
With these you will want to make sure you use indexes to speed up query times.
Hope this helps a bit
Are you restricted at only using that database structure? The reason I ask is that I think the ideal way to do this would be to create a keywords table and associate the keywords with the file ID. So you would still have your files table, but you would no longer put keywords in them. Instead you would create a new table called keywords with a structure similar to:
MYSQL Code: [ Select ]
Keywords Table
+----------+----------------------------------------+
| file_id | keyword |
+----------+----------------------------------------+
| 1 | Test |
| 1 | test 2 |
| 1 | test 3 |
| 2 | team |
| 2 | tetris |
| 3 | Test |
| 3 | te |
| 4 | te |
+----------+----------------------------------------+
| file_id | keyword |
+----------+----------------------------------------+
| 1 | Test |
| 1 | test 2 |
| 1 | test 3 |
| 2 | team |
| 2 | tetris |
| 3 | Test |
| 3 | te |
| 4 | te |
- Keywords Table
- +----------+----------------------------------------+
- | file_id | keyword |
- +----------+----------------------------------------+
- | 1 | Test |
- | 1 | test 2 |
- | 1 | test 3 |
- | 2 | team |
- | 2 | tetris |
- | 3 | Test |
- | 3 | te |
- | 4 | te |
So basically you would list every keyword individually and associate it with the file_id that has it. Then when you do a MySQL query it will let you know exactly what file ids have an exact match on a keyword. For example:
MYSQL Code: [ Select ]
SELECT f.id
FROM files f, keywords k
WHERE f.id = k.file_id
AND k.keyword = 'te'
FROM files f, keywords k
WHERE f.id = k.file_id
AND k.keyword = 'te'
- SELECT f.id
- FROM files f, keywords k
- WHERE f.id = k.file_id
- AND k.keyword = 'te'
That would return file id 3 and 4.
You could also go one step further to prevent keywords from being duplicated over and over in this table and make another keyword table that lists each unique keyword and assigns each one a keyword_id. Then with the table above you would put the keyword_id and the file_id.
With these you will want to make sure you use indexes to speed up query times.
Hope this helps a bit
Ozzu Hosting - Want your website on a fast server like Ozzu?
- ScottG
- Proficient


- Joined: Jul 06, 2010
- Posts: 266
- Status: Offline
I am restricted to that data base structure and i do agree fully with your solution that's how I personally would have done it but I'm rebuilding a system that someone else made and it has been in use for sometime and there are over 100,000 files attached to the system with just as many database records if not more to make things even worse there is also a keywords table which basically duplicates the keywords not only to the files but the keywords themselves. It really is a mess and I've tried to talk them into a full Database redesign but they want to keep the same structure to maintain backward compatibility and so if something goes wrong the can flip back to the old system that currently works, really slow but works.
Here is an example of what I'm dealing with
Category Table
+----------+---------------+------------------------+
| ID | busorgID | display_name |
+----------+----------------------------------------+
| 1 | 1 | cat 1 |
| 2 | 1 | cat 2 |
| 3 | 3 | cat 1 |
| 4 | 2 | cat 1 |
| 5 | 3 | cat 2 |
| 6 | 3 | cat 3 |
| 7 | 1 | cat 3 |
Keywords Table
+----------+---------------+----------------+-----------+
| ID | busorgID | keyword | parentID |
+----------+--------------------------------------------+
| 1 | 1 | Test | 1 |
| 2 | 1 | test 2 | 2 |
| 3 | 1 | test 3 | 7 |
| 4 | 1 | team | 7 |
| 5 | 1 | tetris | 7 |
| 6 | 1 | Test | 1 |
| 7 | 1 | te | 2 |
| 8 | 1 | te | 2 |
| 9 | 2 | tetris | 2 |
| 10 | 2 | Test | 2 |
| 11 | 2 | te | 2 |
| 12 | 2 | te | 5 |
| 13 | 3 | Test | 3 |
| 14 | 3 | te | 3 |
| 15 | 3 | te | 3 |
| 16 | 3 | Test | 5 |
| 17 | 3 | te | 5 |
| 18 | 3 | te | 6 |
As you can see horribly bad Database design and its frustrating because they won't let me redesign or change the tables
so my solution is something similar to what I would have done and you suggested
Keyword Relations Table
+------------+---------------+----------------+
| keyword_id | file_id | rating |
+------------+--------------------------------+
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 1 | 3 |
| 4 | 2 | 5 |
| 5 | 2 | 5 |
| 6 | 2 | 3 |
| 7 | 3 | 2 |
| 8 | 3 | 1 |
The rating is just a sorter flag that the user base the keywords relevance to the picture.
Here is an example of what I'm dealing with
MYSQL Code: [ Select ]
Category Table
+----------+---------------+------------------------+
| ID | busorgID | display_name |
+----------+----------------------------------------+
| 1 | 1 | cat 1 |
| 2 | 1 | cat 2 |
| 3 | 3 | cat 1 |
| 4 | 2 | cat 1 |
| 5 | 3 | cat 2 |
| 6 | 3 | cat 3 |
| 7 | 1 | cat 3 |
Keywords Table
+----------+---------------+----------------+-----------+
| ID | busorgID | keyword | parentID |
+----------+--------------------------------------------+
| 1 | 1 | Test | 1 |
| 2 | 1 | test 2 | 2 |
| 3 | 1 | test 3 | 7 |
| 4 | 1 | team | 7 |
| 5 | 1 | tetris | 7 |
| 6 | 1 | Test | 1 |
| 7 | 1 | te | 2 |
| 8 | 1 | te | 2 |
| 9 | 2 | tetris | 2 |
| 10 | 2 | Test | 2 |
| 11 | 2 | te | 2 |
| 12 | 2 | te | 5 |
| 13 | 3 | Test | 3 |
| 14 | 3 | te | 3 |
| 15 | 3 | te | 3 |
| 16 | 3 | Test | 5 |
| 17 | 3 | te | 5 |
| 18 | 3 | te | 6 |
- Category Table
- +----------+---------------+------------------------+
- | ID | busorgID | display_name |
- +----------+----------------------------------------+
- | 1 | 1 | cat 1 |
- | 2 | 1 | cat 2 |
- | 3 | 3 | cat 1 |
- | 4 | 2 | cat 1 |
- | 5 | 3 | cat 2 |
- | 6 | 3 | cat 3 |
- | 7 | 1 | cat 3 |
- Keywords Table
- +----------+---------------+----------------+-----------+
- | ID | busorgID | keyword | parentID |
- +----------+--------------------------------------------+
- | 1 | 1 | Test | 1 |
- | 2 | 1 | test 2 | 2 |
- | 3 | 1 | test 3 | 7 |
- | 4 | 1 | team | 7 |
- | 5 | 1 | tetris | 7 |
- | 6 | 1 | Test | 1 |
- | 7 | 1 | te | 2 |
- | 8 | 1 | te | 2 |
- | 9 | 2 | tetris | 2 |
- | 10 | 2 | Test | 2 |
- | 11 | 2 | te | 2 |
- | 12 | 2 | te | 5 |
- | 13 | 3 | Test | 3 |
- | 14 | 3 | te | 3 |
- | 15 | 3 | te | 3 |
- | 16 | 3 | Test | 5 |
- | 17 | 3 | te | 5 |
- | 18 | 3 | te | 6 |
As you can see horribly bad Database design and its frustrating because they won't let me redesign or change the tables
so my solution is something similar to what I would have done and you suggested
MYSQL Code: [ Select ]
Keyword Relations Table
+------------+---------------+----------------+
| keyword_id | file_id | rating |
+------------+--------------------------------+
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 1 | 3 |
| 4 | 2 | 5 |
| 5 | 2 | 5 |
| 6 | 2 | 3 |
| 7 | 3 | 2 |
| 8 | 3 | 1 |
- Keyword Relations Table
- +------------+---------------+----------------+
- | keyword_id | file_id | rating |
- +------------+--------------------------------+
- | 1 | 1 | 5 |
- | 2 | 1 | 4 |
- | 3 | 1 | 3 |
- | 4 | 2 | 5 |
- | 5 | 2 | 5 |
- | 6 | 2 | 3 |
- | 7 | 3 | 2 |
- | 8 | 3 | 1 |
The rating is just a sorter flag that the user base the keywords relevance to the picture.
- ScottG
- Proficient


- Joined: Jul 06, 2010
- Posts: 266
- Status: Offline
Page 1 of 1
To Reply to this topic you need to LOGIN or REGISTER. It is free.
Post Information
- Total Posts in this topic: 5 posts
- Users browsing this forum: Bigwebmaster and 198 guests
- You cannot post new topics in this forum
- You cannot reply to topics in this forum
- You cannot edit your posts in this forum
- You cannot delete your posts in this forum
- You cannot post attachments in this forum
