MySQL operator IN () only this values - php

quite a few hours struggling with a problem, it's more about the issue.
Depicting the script when you type in textboxa searches in SQL data records where name = contain. Assuming that I entered 2 names separated by a comma (X, Y) 2:
a) If you choose "all containing typed values" is to look for all the records, in the above "name". It works:
$where. = "AND name IN ('". implode (' ', ' ', $array). "')";
Model: Contains X.
Contains The Y;
Contains the Y and X;
It works as it should.
(b)) If you choose "all containing only the values to be entered to look for records in which only occurs in the" name "is what we have.
Here I do not know how to do it.
Model: contains the X and Y-only, I don't want records that contain only X, but Y and Alternatively, if in MySQL "name" is 3 options (X, Y, Z).
I do not know how to explain more clearly:--------------------example: I have 5 values in the table, where the name is in different combinations:
1) Name1, Name2,
2) name1, Name8,
3) name1, Name9,
4) Name8, Name3,
5) Name4, Name5,
using the selected the first option, where the textbox typed: "Name1, Name" the result will be: 1), 2), 3), 4), this is valid.
Using the second result should only be 2).
The result of a) res1 or res2 or res1 and res2.
Now I need somehow to come to a solution, when I type in textbox "res1, res2" the result will be: only the records that contain res1 and res2, and NOTHING AFTER that.
---- EDIT FOR REPLIES:
+--------------------- my_val_search -----------+
| aid | int(11) | primary key auto_increment|
|name | varchar(255)| |
+-----------------------------------------------+
Records:
1|Ruby
2|CSS
3|HTML
4|PHP
5|Python
6|SQL
7|Javascript
8|C++
9|AJAX
10|Java
+---------------------- topics -----------------+
|id | int(11) | Primary key auto_increment |
|dateline| date | |
|author | varchar(30) | |
|message | text | |
|aid |int(11) |foreign key with my_val_search|
+-----------------------------------------------+
Now if you type in the search "Ruby, Python" I want to have found records only for topics where are "Ruby and Python".
By using the
$myValInput = $_GET['keywords'];
$where = "AND a.name IN('" . implode("','", $myValInput. "')";
Searches for records, where when you type "Python, Ruby" is divided into:
-Python
-Ruby,
- Python and Ruby
and I want to make the results appear only for "Python and Ruby". In addition, if someone types "Python, Ruby, Java," the result should be
-Python, Ruby, Java,
the record should be just what I wrote, nothing more.

Using IN cannot get what you expect!
When used with a subquery, the word IN is an alias for = ANY. Thus, these two statements are the same:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
https://dev.mysql.com/doc/refman/5.7/en/any-in-some-subqueries.html
Besides, I think your schema is incorrect. The topic should be parent and the topic keywords should be child. If I were you, I will do it like this.
CREATE TABLE IF NOT EXISTS `topic` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` date,
`author` varchar(30),
`message` text,
PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `topic_keywords` (
`topic` int(10) unsigned NOT NULL,
`keyword` varchar(255),
FOREIGN KEY (`topic`) REFERENCES `topic` (`id`),
UNIQUE INDEX (`topic`, `keyword`)
) ENGINE=InnoDB;
In your case, I think the full text is suitable.
https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
CREATE TABLE IF NOT EXISTS `topic` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` date,
`author` varchar(30),
`message` text,
`keywords` varchar(255),
PRIMARY KEY(`id`),
FULLTEXT (`keywords`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
INSERT INTO `topic` (`keywords`)
VALUES ('Ruby,Python'),
('Ruby'),
('Ruby,SQL'),
('Python'),
('Python,SQL'),
('Ruby,Python,SQL,AJAX');
SELECT `keywords`
FROM `topic`
WHERE MATCH(`keywords`) AGAINST('+Ruby +Python' IN BOOLEAN MODE);
+----------------------+
| keywords |
+----------------------+
| Ruby,Python |
| Ruby,Python,SQL,AJAX |
+----------------------+
2 rows in set (0.00 sec)
If you just find out the records just exact your input. You can add a hash column. Like design a hash table for your Mysql table. So you can use hash value in your query statement. But don't forget to update the hash value, if your keywords value had been changed. Add the before update trigger might be a good choice.
CREATE TABLE IF NOT EXISTS `topic` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`dateline` date,
`author` varchar(30),
`message` text,
`keywords` varchar(255),
`keywords_hash` varchar(32),
PRIMARY KEY(`id`),
FULLTEXT (`keywords`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
INSERT INTO `topic`
(`keywords` , `keywords_hash`)
VALUES ('Ruby,Python', md5('Ruby,Python'));
SELECT `keywords`
FROM `topic`
WHERE `keywords_hash` = md5('Ruby,Python');

Here's an attempt at a solution, but there's better solutions query wise than using a regular denormalized structure to handle this - so if you're going to query this a lot (and with a large number of terms), you might want to look into caching the lookup values in your original table and then querying by their content. Anyway, to solve it with regular joins:
Given data:
CREATE TABLE foo (id int);
CREATE TABLE foo_bar (foo_id int, bar_id int);
CREATE TABLE bar (id int, name varchar(25));
INSERT INTO foo VALUES (1), (2), (3), (4);
INSERT INTO bar VALUES (1, 'Ruby'), (2, 'Python'), (3, 'PHP');
INSERT INTO foo_bar VALUES (1, 1), (2, 1), (3, 3), (4, 3), (2,2);
You can retrieve id values from foo that has both Ruby and Python by joining each term manually:
SELECT f.id FROM foo f
JOIN foo_bar fb ON fb.foo_id = f.id
JOIN bar b ON fb.bar_id = b.id AND b.name = 'Ruby'
JOIN foo_bar fb2 ON fb2.foo_id = f.id
JOIN bar b2 ON fb2.bar_id = b2.id AND b2.name = 'Python'
This gives 2 as the only id that haves all languages present.

Related

MySQL: "Patch" existing data on a table from values in another table

I have two tables, identical in structure. First one is populated with records obtained from another system that potentially needs corrections (could be one or many columns). Second table is corrections that I want to apply to the first table.
For example, I could have the following rows on table1:
order_number | name | email | tracking_no
101 null foo#bar.com 3456789
102 An Example ex#ample.com 1010101
...and the corrections I want to apply to these rows on table2:
order_number | name | email | tracking_no
101 Name Surname null null
102 null null 45778901
Essentially: Add missing name to order_number 101 and correct the wrong tracking_no for order_number 102.
The logic of what I am trying to do is: "Patch" values in table1 with the corrections contained for the same order_number in table2, giving precedence over to values in table2 and not overwriting existing values in table1 if the corresponding value in table2 is a null.
For the case where a value is null in table1 and we have a non-null correction in table2, COALESCE seems to be the right way to go but I can't figure out how to overwrite an already existing value with the corresponding "fix" from table2.
Is there a mechanism in MySQL/MariaDB that would allow me to do this as the alternative is a very messy "pull two records from two tables, compare values and build up the new correct record and insert it back into table1".
As pointed out in comments, here is a reproducible set of test data along with table structures:
USE so_demo;
DROP TABLE IF EXISTS so_demo.table1;
DROP TABLE IF EXISTS so_demo.table2;
CREATE TABLE so_demo.table1 (
order_number int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) DEFAULT NULL,
email varchar(250) DEFAULT NULL,
tracking_no varchar(255) DEFAULT NULL,
PRIMARY KEY (order_number),
UNIQUE INDEX UK_table1_order_number (order_number)
)
ENGINE = INNODB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;
CREATE TABLE so_demo.table2 (
order_number int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) DEFAULT NULL,
email varchar(250) DEFAULT NULL,
tracking_no varchar(255) DEFAULT NULL,
PRIMARY KEY (order_number),
UNIQUE INDEX UK_table2_order_number (order_number)
)
ENGINE = INNODB,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;
INSERT INTO so_demo.table1 VALUES (101, NULL, "foo#bar.com", 3456789);
INSERT INTO so_demo.table1 VALUES (102, "An Example", "ex#ample.com", 1010101);
INSERT INTO so_demo.table2 VALUES (101, "Name Surname", NULL, NULL);
INSERT INTO so_demo.table2 VALUES (102, NULL, NULL, 45778901);
The term you are looking for is merge and in mysql an insert on duplicate key
drop table if exists t,t1;
create table t(order_number int primary key, name varchar(20) , email varchar(20), tracking_no int);
insert into t values
(101 , null , 'foo#bar.com' , 3456789),
(102 , 'An Example', 'ex#ample.com' , 1010101);
create table t1(order_number int, name varchar(20), email varchar(20), tracking_no int);
insert into t1 values
(101 , 'Name Surname', null , null),
(102 , null , null , '45778901');
insert into t
select * from t1
on duplicate key update
t.name = case when t1.name is not null then t1.name else t.name end,
t.email = case when t1.email is not null then t1.email else t.email end,
t.tracking_no = case when t1.tracking_no is not null then t1.tracking_no else t.tracking_no end
;
select * from t;
+--------------+--------------+--------------+-------------+
| order_number | name | email | tracking_no |
+--------------+--------------+--------------+-------------+
| 101 | Name Surname | foo#bar.com | 3456789 |
| 102 | An Example | ex#ample.com | 45778901 |
+--------------+--------------+--------------+-------------+
2 rows in set (0.001 sec)

Mysql Select specific data from 2 tables base on the third table

I have three tables
tbl_project
db_projectid db_projectname
1 test
2 xxx
tbl_activities
db_id db_projectid db_category
1 1 Civil Work
2 1 Mechanical
3 1 Electrical
tbl_dailypercentage
db_dpid db_aid db_projectid db_status
1 1 1 red
2 1 1
3 2 1
db_projectid is a primary key in tbl_project
db_id is a primary key and db_projectid is a foreign key in tbl_activities
db_dpid is a primary key and db_aid is a foreign key in tbl_dailypercentage
I tried this query
select
activities.db_id,
activities.db_category as cat,
dailypercentage.db_status,
dailypercentage.db_aid,
dailypercentage.db_projectid
from tbl_activities as activities,tbl_dailypercentage as dailypercentage
where
dailypercentage.db_projectid='$projectId'
and
activities.db_id=dailypercentage.db_aid
and
dailypercentage.db_status='red'
But i Have ab error
Undefined variable: cat
while($row=mysqli_fetch_array($statusQuery)){
$status=$row['db_status'];
$cat=$row['cat'];
}
<td> <?php if($cat=="Civil Work" && $status="red"){
echo"<p style='color:$status'>".($sumcivil/$civilCount)."</p>";}
else{echo ($sumcivil/$civilCount);}?>
</td>
I try also many thing the left join and the right join
to have the result i want
The Result i want is
For Project who have an id=1
category status
civil work red
mechanical work
electrical work
For Project who have an id=2
category status
civil work
mechanical work
electrical work
You showed this code:
while($row=mysqli_fetch_array($statusQuery)){
$status=$row['db_status'];
$cat=$row['cat'];
}
If your query returns no rows, $status and $cat will never get defined. I guess this is what went wrong. What happens if you run that query with a MySQL client like phpMyadmin?
Similarly, if your query returns more than one row, $status and $cat will capture the values of only the last row.
It's important to work out what you want to happen with no rows and multiple rows.
Based only on the tables in your question I have put together the following schema (I've not added constraints to the foreign keys as this is just for testing).
create table tbl_project (
`db_projectid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`db_projectname` VARCHAR(255) NOT NULL DEFAULT 'Undefined',
PRIMARY KEY (`db_projectid`)
);
create table tbl_activities (
`db_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`db_projectid` INT(1) NOT NULL,
`db_category` VARCHAR(255) NOT NULL DEFAULT 'Undefined',
PRIMARY KEY (`db_id`)
);
create table tbl_dailypercentage (
`db_dpid` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`db_aid` INT(1) NOT NULL,
`db_projectid` INT(1) NOT NULL,
`db_status` VARCHAR(255) NULL,
PRIMARY KEY (`db_dpid`)
);
insert into tbl_project (db_projectname) values ('Test'), ('xxx');
insert into tbl_activities (db_projectid, db_category) values ('1', 'Civil Work'), ('1', 'Mechanical'), ('1', 'Electrical');
insert into tbl_dailypercentage (db_aid, db_projectid, db_status) values
('1', '1', 'red'),
('1', '1', null),
('2', '1', null);
select a.db_category as cat, dp.db_status from tbl_project p
left join tbl_activities a on p.db_projectid = a.db_projectid
left join tbl_dailypercentage dp on dp.db_aid = a.db_id
where p.db_projectid = 1
group by a.db_id;
I've had to add the group by into the final query as you have multiple rows in tbl_dailypercentage with the same db_aid and db_projectid values.
After that, you want to tweak your php code, putting the td stuff inside the while loop:
<?php while($row=mysqli_fetch_array($statusQuery)):?>
$status=$row['db_status'];
$cat=$row['cat'];
<td> <?php if($cat=="Civil Work" && $status="red"){
echo"<p style='color:$status'>".($sumcivil/$civilCount)."</p>";}
else{echo ($sumcivil/$civilCount);}?>
</td>
<?php endwhile; ?>

MySQL for Test Website

I am making a website similar to Moodle. It basically holds tests for students. The confusion comes in when allowing multiple types of questions on the tests and how to create the tables to store the data.
The test_info table will contain the test ID and description.
The test table will contain Test ID and Question ID pairs.
To get the questions for a test this will require a "SELECT * FROM test WHERE testID=$tID" which will take a substantial amount of time to execute when the database gets large.
Originally the questions table contained the question, 4 possibilities and the answer.
How should I store the data for multiple questions and multiple types of questions in a database?
For Example:
Test 51 - "Intro Mathmatics"
Question 1: What is 2+2?
A: 4 B: 12
C: 7 D: 8
Question 2: (0,103) is the range for the equation y=2x/(100x)?
True False
This results in data with 2 different sizes
Questions:
| Question | A | B | C | D | Correct |
| Question | Correct |
If I store these in 1 table it will waste 4 50Char Var-Chars per question and if I store these in 2 separate tables, how will the SELECT know which table to select from?
Questions:
| TestID | TableID | QuestionID |
Questions1:
| Ques | A | B | C | D | Correct |
Questions2:
| Ques | A | B | C | D | Correct |
What a nightmare.
Put the answer in their own table:
answers (answer_id, question_id, description, sequence)
and put the correct answer_id in the question table.
An empty VARCHAR(50) only needs six bits, which means that it will (most likely) take up one byte only on the disk. The VAR in VARCHAR means that the space usage will adapt to the actual data. This means that using one table will "waste" only four bytes per question.
Since you have two types of questions that you handle in two different ways in the code, your two-table approach is viable as well.
The recommended approach is:
Note that four-answer questions and yes-no questions are both special cases of a multiple-choice question. Store these in the database. One possible schema:
question: question_id (PK), test_id (FK), text
answer: answer_id (PK), question_id (FK), text, is_correct
PK = primary key, FK = foreign key
I think you data structure will be like this:
Table1 :Test
id:
TestName:
Table2: Questions:
id:
test_id:
Question:
Answer: //say a,b,c,d
Table3:Answers
id:
question_id:
Anwser Option: //say a,b,c,d
Answer:
Sql For tables with data:
The data will help you in understanding the structure.
CREATE TABLE IF NOT EXISTS `Tests` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Test` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
--
-- Dumping data for table `test2`
--
INSERT INTO `test2` (`id`, `Test`) VALUES
(1, 'Test1');
//////////////////////////////////////
CREATE TABLE IF NOT EXISTS `questions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`test_id` int(11) NOT NULL,
`Question` varchar(255) NOT NULL,
`Answer` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
--
-- Dumping data for table `questions`
--
INSERT INTO `questions` (`id`, `test_id`, `Question`, `Answer`) VALUES
(1, 1, 'question1', 'a'),
(2, 2, 'Question2', 'd');
////////////////////////////////////////////////////
CREATE TABLE IF NOT EXISTS `answers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL,
`answer_option` varchar(10) NOT NULL,
`Answer` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
--
-- Dumping data for table `answers`
--
INSERT INTO `answers` (`id`, `question_id`, `answer_option`, `Answer`) VALUES
(1, 1, 'a', 'True'),
(2, 1, 'b', 'False'),
(3, 2, 'a', 'Asnwer1'),
(4, 2, 'b', 'Answer2'),
(5, 2, 'c', 'Answer3'),
(6, 2, 'd', 'Answer4'),
(7, 2, 'e', 'Answer5');

Distinct Table field tags

I have a table with a field (cat_tags) which contain the following rows:-
id - cat_tags - date_added
1 - yam, potato, onion, pepper,beans - 23-12-2011
row1 - yam, potato, onion, pepper 23-12-2011
row2 - onion, pepper, beans - 23-12-2011
row3 - pepper, beans, rice - 23-12-2011
row4 - rice, potato, pepper, yam - 23-12-2011
row5 - beans, rice, onion, food - 23-12-2011
.....
.....
.....
pls how can I get a DISTINCT list of items and the number of times(frequency) they occurred in the entire table field?
Eg. pepper x 4
onion x 3
yam x 2
thank you in advance
First normalize your table(s).
Table tags
id unsigned integer autoincrement primary key,
tag varchar(40) not null,
unique index tag(tag)
Table Item_tags
id unsigned integer autoincrement primary key,
tag_id integer not null,
item_id integer not null
Table items
id unsigned integer autoincrement primary key,
date_added date not null
Insert an item into your database using the following series of queries:
INSERT INTO Items VALUES (null, NOW());
SELECT #last_item_id:= LAST_INSERT_ID();
REPLACE IGNORE INTO tags (tag) VALUES ('pepper', 'onion', 'rice')
INSERT INTO Item_tags
SELECT
null as id
, tags.id
, last_item_id
FROM tags WHERE tags.tag IN ('pepper', 'onion', 'rice')
If you want to simplify the addition of items and streamline your php code,
use a blackhole table and a trigger on that table.
CREATE TABLE bh_items (
id unsigned integer autoincrement primary key,
date_added timestamp,
tag1 varchar(45) not null,
tag2 varchar(45) default null,
tag3 varchar(45) default null,
tag4 varchar(45) default null,
tag5 varchar(45) default null,
tag6 varchar(45) default null,
tag7 varchar(45) default null,
tag8 varchar(45) default null,
tag9 varchar(45) default null,
tag10 varchar(45) default null) ENGINE = blackhole;
DELIMITER $$
CREATE TRIGGER ai_bn_items_each AFTER INSERT ON bh_items FOR EACH ROW
BEGIN
DECLARE last_item_id integer;
INSERT INTO Items VALUES (null, new.date_added);
SELECT LAST_INSERT_ID() INTO last_item_id;
REPLACE IGNORE INTO tags ((null, new.tag1)
,(null, new.tag2)
,(null, new.tag3)
,(null, new.tag4)
,(null, new.tag5)
,(null, new.tag6)
,(null, new.tag7)
,(null, new.tag8)
,(null, new.tag9)
,(null, new.tag10));
INSERT IGNORE INTO item_tags (item_id, tag_id)
SELECT last_item_id, tags.tag FROM tags
WHERE tags.tag
IN (new.tag1, new.tag2, new.tag3, new.tag4, new,tag5
, new.tag6, new.tag7, new.tag8, new.tag9, new.tag10);
END $$
DELIMITER ;
If you use the trigger you can just insert into the blackhole table and the trigger will then update all your 3 tables.
INSERT INTO bh_items VALUES (null, null, 'onion', 'rice', 'pepper'
, null, null, null, null, null, null, null)
All your tables will be automagically updated.
Back to your question
You can then select from this using this query:
SELECT tags.tag, COUNT(*) as freq FROM item_tags
INNER JOIN tags ON (item_tags.tag_id = tags.id)
GROUP BY item_tags.tag_id
Links:
blackhole: http://dev.mysql.com/doc/refman/5.1/en/blackhole-storage-engine.html
replace into: http://dev.mysql.com/doc/refman/5.1/en/replace.html
Triggers: http://dev.mysql.com/doc/refman/5.1/en/triggers.html
Create table: http://dev.mysql.com/doc/refman/5.1/en/create-table.html
If I have understood your question correctly, this should work:
$result = mysql_query("SELECT cat_tags FROM table");
while($row = mysql_fetch_array($result))
{
//Split the row into an array based on the comma
$detail_array = explode(",", $row['cat_tags']);
//Go through that array and index a master count for each occurence of the same value
//Trim due to the spaces after the comma in your field
foreach($detail_array as $key=>$val)
{
$output_array[trim($val)] = $output_array[trim($val)] + 1;
}
}
print_r($output_array);
You should first normalize your table structure.
It is not compliant with the first normal form, making the requested operation way more complicated than it needs to be.

split keywords for post php mysql

i have one table store post id and it's tags like :
Post_id | Tags
--------------------------------------
1 | keyword1,keyword2,keyword3
I want to loop though each row at this table and do :
put the keyword1,keyword2,keyword3 in new table :
word_id | word_value
-------------------------
1 | keyword1
2 | keyword2
3 | keyword3
get mysql_insert_id() foreach (or exist word_id if word_value already there) and then put in the new table like :
post_id | word_id
------------------
1 | 1
1 | 2
1 | 3
I've using php and mysql for do that task but this is slowly. Anyone have good idea?
do something like this:
-- TABLES
drop table if exists post_tags;
create table post_tags
(
post_id int unsigned not null auto_increment primary key,
tags_csv varchar(1024) not null
)
engine=innodb;
drop table if exists keywords;
create table keywords
(
keyword_id mediumint unsigned not null auto_increment primary key,
name varchar(255) unique not null
)
engine=innodb;
-- optimised for queries such as - select all posts that have keyword 3
drop table if exists post_keywords;
create table post_keywords
(
keyword_id mediumint unsigned not null,
post_id int unsigned not null,
primary key (keyword_id, post_id), -- clustered composite PK !
key (post_id)
)
engine=innodb;
-- STORED PROCEDURES
drop procedure if exists normalise_post_tags;
delimiter #
create procedure normalise_post_tags()
proc_main:begin
declare v_cursor_done tinyint unsigned default 0;
-- watch out for variable names that have the same names as fields !!
declare v_post_id int unsigned;
declare v_tags_csv varchar(1024);
declare v_keyword varchar(255);
declare v_keyword_id mediumint unsigned;
declare v_tags_done tinyint unsigned;
declare v_tags_idx int unsigned;
declare v_cursor cursor for select post_id, tags_csv from post_tags order by post_id;
declare continue handler for not found set v_cursor_done = 1;
set autocommit = 0;
open v_cursor;
repeat
fetch v_cursor into v_post_id, v_tags_csv;
-- split the out the v_tags_csv and insert
set v_tags_done = 0;
set v_tags_idx = 1;
while not v_tags_done do
set v_keyword = substring(v_tags_csv, v_tags_idx,
if(locate(',', v_tags_csv, v_tags_idx) > 0,
locate(',', v_tags_csv, v_tags_idx) - v_tags_idx,
length(v_tags_csv)));
if length(v_keyword) > 0 then
set v_tags_idx = v_tags_idx + length(v_keyword) + 1;
set v_keyword = trim(v_keyword);
-- add the keyword if it doesnt already exist
insert ignore into keywords (name) values (v_keyword);
select keyword_id into v_keyword_id from keywords where name = v_keyword;
-- add the post_keywords
insert ignore into post_keywords (keyword_id, post_id) values (v_keyword_id, v_post_id);
else
set v_tags_done = 1;
end if;
end while;
until v_cursor_done end repeat;
close v_cursor;
commit;
end proc_main #
delimiter ;
-- TEST DATA
insert into post_tags (tags_csv) values
('keyword1,keyword2,keyword3'),
('keyword1,keyword5'),
('keyword4,keyword3,keyword6,keyword1');
-- TESTING
call normalise_post_tags();
select * from post_tags order by post_id;
select * from keywords order by keyword_id;
select * from post_keywords order by keyword_id, post_id;
for each keyword, do
insert into newtable (id, keyword) select id, 'aKeyword' from oldtable where oldtable.keywords like '%aKeyword%'
if oldtable.keywords is just a VARCHAR, or
insert into newtable (id, keyword) select id, 'aKeyword' from oldtable where FIND_IN_SET('aKeyword',keywords)>0
if it's a SET type.

Categories