I know how to pipe one MySQL query into another:
SELECT user_name FROM users WHERE user_id=( SELECT user_id FROM entries WHERE header="foo" );
Out of pure intellectual curiosity, how I dynamically choose a column or a table?
Ex:
SELECT (
SELECT column_name FROM column_names WHERE id = 1
) FROM (
SELECT table_name FROM table_names WHERE id = 1
);
Use a prepared statement:
mysql> SET #sql = CONCAT("SELECT ", (SELECT "NOW()"));
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #sql;
+--------------+
| #sql |
+--------------+
| SELECT NOW() |
+--------------+
1 row in set (0.00 sec)
mysql> PREPARE stmt FROM #sql;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE stmt;
+---------------------+
| NOW() |
+---------------------+
| 2009-04-06 23:08:31 |
+---------------------+
1 row in set (0.00 sec)
I'm pretty sure this is impossible with a regular query or view.
In answer to your first question, you should learn about how to do JOIN in SQL. A join is a fundamental operation in the SQL language. It's as important is understanding how to do a loop in other languages.
SELECT DISTINCT users.user_name
FROM users JOIN entries USING (user_id)
WHERE entries.header = 'foo';
Regarding your second question, no, you can't make table names or column names dynamic within a single statement.
However, you can write code in your application to build a SQL statement as a string, based on looking up column names and table names. Then execute the resulting string as a new SQL query.
You can do it by querying the information_schema.columns table.
Do this and check the results. I'm not sure what you're trying to do but that table contains anything related to your columns:
SELECT * FROM information_schema.`COLUMNS` C;
BTW, I don't know any way of doing this in a single query. You should get the columns information and then create a new query in your coding language, whatever that is.
Related
I have a lot of WP websites set up on my server, and I'm trying to get a list of admin email addresses registered for all of the WP sites.
The server uses WHM/cPanel, and MariaDB.
I'd hoped WordPress Toolkit could do this out of the box, but it doesn't seem to be able to.
I'm an SQL noob, and I've only gotten as far as this for my SQL query, for a single DB:
SELECT option_value
FROM `database_name`.`wp_options`
WHERE option_name="admin_email"
Another problem is, lots of the WP databases on the server don't use the standard wp_ table prefix, but instead use a random string, so I also need a way of using a wildcard in the table name like
*_options
So my 2 problems are:
Make the query loop across ALL databases on the server
make the query use a wildcard in the table name
Is this possible?
Yes. Its two queries, first to generate the SQL, and then execute it.
Example setup:
MariaDB [(none)]> create database rr;
Query OK, 1 row affected (0.000 sec)
MariaDB [(none)]> create database ss;
Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> create table ss.wp_options(option_name varchar(30), option_value varchar(30));
Query OK, 0 rows affected (0.003 sec)
MariaDB [(none)]> create table rr.rr_options(option_name varchar(30), option_value varchar(30));
Query OK, 0 rows affected (0.003 sec)
MariaDB [(none)]> insert into ss.wp_options values ('admin_email', 'me#ss');
Query OK, 1 row affected (0.003 sec)
MariaDB [(none)]> insert into rr.rr_options values ('admin_email', 'me#rr');
Query OK, 1 row affected (0.002 sec)
Then use the information_schema.TABLES to generate your query using UNION ALL to concatinate them:
SELECT group_concat(
concat('select "', TABLE_SCHEMA, '" as db, option_value from ', TABLE_SCHEMA, '.', TABLE_NAME, ' WHERE option_name="admin_email"')
SEPARATOR ' UNION ALL ') INTO #sql
FROM information_schema.TABLES
WHERE TABLE_NAME LIKE '%_options';
Just to show what we generate:
MariaDB [(none)]> select #sql\G
*************************** 1. row ***************************
#sql: select "ss" as db, option_value from ss.wp_options WHERE option_name="admin_email"
UNION ALL select "rr" as db, option_value from rr.rr_options WHERE option_name="admin_email"
Execute immediate runs a query, like a prepared statement without the setup and run, shutdown steps:
MariaDB [(none)]> execute immediate #sql;
+----+--------------+
| db | option_value |
+----+--------------+
| ss | me#ss |
| rr | me#rr |
+----+--------------+
2 rows in set (0.002 sec)
I have two tables in a legacy database. One of them contains a field containing some xml. This other table contains the tags that constitutes the xml.
For example consider a table with a list of languages (e.g. en, fr, it) and a table with a field like
<en>Something</en><fr>Quelque chose</fr><it>Qualcosa</it>
I would like to extract all the translations. I have a query that goes like
SELECT GROUP_CONCAT(extractvalue(table.field, languages.sigla))
FROM table, languages
GROUP BY table.id
But I get the following error
[HY000][1105] Only constant XPATH queries are supported
I guess this is a limitation of MySql (I'm usign version 5.6). Is there any other way to obtain what I'm looking for?
One option you can try is (adjust as needed):
mysql> SELECT
-> GROUP_CONCAT('SELECT ExtractValue(#`xml`, \'', `der`.`lang`, '\') `lang`' SEPARATOR ' UNION ALL ') INTO #`query`
-> FROM (
-> SELECT 'en' `lang`
-> UNION
-> SELECT 'fr'
-> UNION
-> SELECT 'it'
-> ) `der`;
Query OK, 1 row affected (0.00 sec)
mysql> SET #`xml` := '<en>Something</en><fr>Quelque chose</fr><it>Qualcosa</it>';
Query OK, 0 rows affected (0.00 sec)
mysql> SET #`query` := CONCAT('SELECT GROUP_CONCAT(`der`.`lang`)
'> FROM (', #`query`, ') `der`');
Query OK, 0 rows affected (0.00 sec)
mysql> PREPARE `stmt` FROM #`query`;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE `stmt`;
+----------------------------------+
| GROUP_CONCAT(`der`.`lang`) |
+----------------------------------+
| Something,Quelque chose,Qualcosa |
+----------------------------------+
1 row in set (0.00 sec)
mysql> DEALLOCATE PREPARE `stmt`;
Query OK, 0 rows affected (0.00 sec)
I faced the same problem and found an easy workaround in that blog post : http://sql-debug.blogspot.com/2012/05/extractvalue-only-constant-xpath.html
The solution is really surprising, but as silly as it can seem, it works perfectly...
It consists in creating a function that only "wraps" the ExtractValue function, in order to give it the xpath as an already generated string.
delimiter ##
create function exv(xml text, xpath text) returns text charset utf8
begin
return cast(extractvalue(xml, xpath) as char);
end ##
delimiter ;
And then, just replace extractvalue with exv in the query you tried to run when you got this [HY000][1105] error.
Of course, this workaround has a performance cost...
I'm working on my project in php [handling students attendance system]. I have a list of students along with their unique id[jntuno] and I need to create a database in mysql for storing the daily attendance of each student for each subject. So I created my tables in this way :
I have a table students in mysql with the following fields and data in it :
now I want to create a new table with the each of the values in the jntuno field as a columns of my new table.
I want my new table [let us name it attendance] to have columns like this :
+------------+-----------+----------+-----------+-----------+
|11341A0501 |11341A0502 |11341A0503|11341A0504 |11341A0505 |......
+------------+-----------+----------+-----------+-----------+
| | | | | |
How to do this in mysql ?
I will later add 3 fields to the attendance table namely :
-> date[the date on which a particular subject is taught] ,
->subject[the name of the subject taught] and
->hours taught[the number of hours for which a particular subject is taught(can be 1 or 2 or 3 ... upto 6)]
every subject taught on a particular date will be adding a new row to the attendance table
Example:
+------------+-----------+-----------------+------------+-----------+----------+-----------+-----------+
|date |subject | classes taught |11341A0501 |11341A0502 |11341A0503|11341A0504 |11341A0505 |..
+------------+-----------+-----------------+------------+-----------+----------+-----------+-----------+
|2013-09-31 |OOPS |3 |2 |3 |0 |1 |3 |
I choose the tables in this way so that the entry of attendance into the table would be more faster.
But many call this a BAD DATABASE STRUCTURE . So please suggest me if there's some other good and efficient database design for my problem
Create the new table with the following statements:
select #s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') from students;
prepare stmt from #s;
execute stmt;
deallocate prepare stmt;
observe how the CREATE TABLE is constructed using the group_concat
Demo: SQL Fiddle
In case you also want to insert the names, this is the statement to it:
select #s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') from students;
prepare stmt from #s;
execute stmt;
deallocate prepare stmt;
select * from students_col;
Here is my whole trail:
mysql> drop table if exists students;
Query OK, 0 rows affected (0.00 sec)
mysql> create table students (slno integer, jntunno char(10), name varchar(50));
Query OK, 0 rows affected (0.07 sec)
mysql> insert into students values (1,'1134A0501','ADARI GOPI');
Query OK, 1 row affected (0.00 sec)
mysql> insert into students values (2,'1134A0502','BALU');
Query OK, 1 row affected (0.00 sec)
mysql> insert into students values (3,'1134A0503','GEETHA');
Query OK, 1 row affected (0.00 sec)
mysql> drop table if exists students_col;
Query OK, 0 rows affected (0.00 sec)
mysql> select #s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') from students;
+-----------------------------------------------------------------------------------------------+
| #s:=concat('create table students_col (',group_concat(jntunno,' CHAR(10)' order by slno),')') |
+-----------------------------------------------------------------------------------------------+
| create table students_col (1134A0501 CHAR(10),1134A0502 CHAR(10),1134A0503 CHAR(10)) |
+-----------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> prepare stmt from #s;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> execute stmt;
Query OK, 0 rows affected (0.21 sec)
mysql> deallocate prepare stmt;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> select #s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') from students;
+------------------------------------------------------------------------------------------------------+
| #s:=concat('insert into students_col values (',group_concat(concat('"',name,'"') order by slno),')') |
+------------------------------------------------------------------------------------------------------+
| insert into students_col values ("ADARI GOPI","BALU","GEETHA") |
+------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> prepare stmt from #s;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> execute stmt;
Query OK, 1 row affected (0.00 sec)
mysql> deallocate prepare stmt;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> select * from students_col;
+------------+-----------+-----------+
| 1134A0501 | 1134A0502 | 1134A0503 |
+------------+-----------+-----------+
| ADARI GOPI | BALU | GEETHA |
+------------+-----------+-----------+
1 row in set (0.00 sec)
mysql>
This procedure will do the work:
DELIMITER ||
DROP PROCEDURE IF EXISTS `test`.`pivot`;
CREATE PROCEDURE `test`.`pivot`()
MODIFIES SQL DATA
BEGIN
DROP TABLE IF EXISTS `test`.`new_table`;
SELECT GROUP_CONCAT(CONCAT(`jntunno`, ' CHAR(10) NOT NULL') SEPARATOR ', ') FROM `test`.`students` INTO #sql;
SET #sql := CONCAT('CREATE TABLE `test`.`new_table` (', #sql, ') ENGINE=InnoDB;');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #sql := NULL;
END;
||
DELIMITER ;
If you cannot use stored procedures, you can easily translate that code into PHP, or any language you use.
create table new_table
select distinct jntuno from students;
or
create table new_table (jntuno varchar(10));
insert into new_table
select distinct jntuno from students;
try
create table new_table (jntuno varchar(10),fieldsname varchar(10));
insert into new_table(jntuno,fieldsname)
values(select distinct jntuno from s tudents,'test');
I'm going to try an answer your question of how to better design this DB:
The Explanation:
Instead of having a column for each student and I assume a row for each day, you should set the table up to have a row for each student x by each day and you can use foreign keys to enforce data integrity
The main reason for this is generally something like the number of students is not a static number. In order to optimize your data usage in a setup like this you would essentially need to recreate the table every time a student is added or removed.
So if you start out with 30 students you then have a table with 30 columns, if then the number of students drops to 15 every time you add a record you are creating 15 unused values and this will gradually take up a lot more storage than you actually need.
Solution:
If you structure your attendance table like this:
attendance ID | JNTUNO | Date | Subject | Hours
Attendance id will simply be a unique identifier for the row, I would suggest either a guid or an auto incremented int
JNTUNO would be a foreign key, pointing back to your Student table
This way on the scenario I presented earlier, with 30 students you will add 30 rows every day with 5 values each but when your number of students changes to 15 you add only 15 rows.
I don't know MYSQL syntax very well but if you'd like I can try to piece together a concrete implementation if my explanation isn't clear; just let me know.
You don't want to be adding columns every time you add a student.
I'd design it like this:
Table: Attendance
Columns:
Date
Subject
ClassNumber
Missed_jntuno
Then you add a row for each student/class combo that is missed (or, if students miss more than they attend, you might want to flip that to a Attended_jntuno field instead and add the row when they make it to class — or if you're really feeling completest, always write a row for every student and then have another bit/boolean column for attended or not).
One advantage to this way is that you can see which classes got which students in addition to a daily sum. Another is that this is much friendlier to things like OLAP cubes for flexible reporting.
declare #s as varchar(8000);
declare #s2 as varchar(25);
set #s ='create table attendance (';
declare s1 cursor
for
select jntunno from students
OPEN s1
fetch next from s1 into #s2
set #s = #s +'['+#s2 +'] numeric(4,2)'
fetch next from s1 into #s2
WHILE ##FETCH_STATUS = 0
BEGIN
set #s = #s +',['+#s2 +'] numeric(4,2)'
fetch next from s1 into #s2
end
CLOSE s1 -- close the cursor
DEALLOCATE s1
set #s = #s+')'
exec(#s)
Basic database design is jumping up right now and shouting in your face: "You're doing it wrong!".
What you're trying to do here is put a many to many relationship in 1 table, while it should actually be in 3 tables.
What you should do is keep your student table as-is and add a subjects table with 1 row for each subject, but not including the date.
Then you want to have another table Attendance with a reference column to Student ID, a reference column to subject ID, a Date field and a Presence field.
What you're trying to do right now is trying to store what's basically volatile data in your metadata about your table, which you should never do. For example, what if you have a student join your school 1 week into the grade? then your table suddenly gets an extra column with no values for the first week.
In addition, your system means that database queries are much harder, since you're storing data you want to filter on in your column header. Other people in here have given a number of reasons why this is a bad idea.
I've reduced my issue down to this simple SP. The column names are getting cached in the SELECT * at the end. I have no idea why or how to stop it. I tried adding SQL_NO_CACHE but that makes no difference.
DROP TABLE IF EXISTS foo;
CREATE TABLE foo(
col1 int,
col2 int);
INSERT INTO foo VALUES(1,2),(3,4),(5,6);
DROP PROCEDURE IF EXISTS mysp;
DELIMITER ;;
CREATE DEFINER=root#localhost PROCEDURE mysp(c INT)
BEGIN
DROP TABLE IF EXISTS mydata;
SET #mycol='col1';
IF c > 0 THEN SET #mycol:='col2';
END IF;
SET #s=CONCAT('CREATE TEMPORARY TABLE mydata AS SELECT ', #mycol, ' FROM foo');
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- The following select call fails on 2nd and subsequent executions of the SP
SELECT SQL_NO_CACHE * FROM mydata;
SELECT "Please see new temp table mydata" as Result;
END ;;
DELIMITER ;
Version
mysql> SELECT VERSION();
+------------+
| VERSION() |
+------------+
| 5.5.15-log |
+------------+
1 row in set (0.00 sec)
First run works fine as expected
mysql> CALL mysp(0);
+------+
| col1 |
+------+
| 1 |
| 3 |
| 5 |
+------+
3 rows in set (0.17 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.17 sec)
Query OK, 0 rows affected (0.17 sec)
Now if I try and run it again using the other column
mysql> CALL mysp(1);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col1' in 'field list'
mysql> SELECT #mycol;
+--------+
| #mycol |
+--------+
| col2 |
+--------+
1 row in set (0.00 sec)
If I recreate the storedprocedure again its works
mysql> CALL mysp(1);
+------+
| col2 |
+------+
| 2 |
| 4 |
| 6 |
+------+
3 rows in set (0.18 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.18 sec)
Query OK, 0 rows affected (0.18 sec)
But if I try switching back to the first column - even if I try dropping the temp table first - it still doesn't work
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col2' in 'field list'
mysql> DROP TABLE mydata;
Query OK, 0 rows affected (0.03 sec)
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'qlgqp1.mydata.col2' in 'field list'
mysql>
*Additional info asked for by eggyal. Also I tried this on another mysql version with same result. *
mysql> CALL mysp(1);
+------+
| col2 |
+------+
| 2 |
| 4 |
| 6 |
+------+
3 rows in set (0.20 sec)
+----------------------------------+
| Result |
+----------------------------------+
| Please see new temp table mydata |
+----------------------------------+
1 row in set (0.20 sec)
Query OK, 0 rows affected (0.20 sec)
mysql> describe mydata;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col2 | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> CALL mysp(0);
ERROR 1054 (42S22): Unknown column 'test.mydata.col2' in 'field list'
mysql> describe mydata;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1 | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
Interesting development of a fix - changing the last few lines to a prepared statement works - but using exactly the same query as before.
-- The following select call fails on 2nd and subsequent executions of the SP
PREPARE stmt FROM 'SELECT SQL_NO_CACHE * FROM mydata';
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT "Please see new temp table mydata" as Result;
MySQL is reusing the statement that was prepared on the previous execution. It's not really "caching" column names; what it's "caching" (if you will) is the prepared statement.
The easy workaround is to use dynamic SQL statement to gain control over the behavior, and avoid the reuse of the previously prepared statement:
SET #s=CONCAT('SELECT ',#mycol,' FROM mydata');
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
It's not matter of the column names being "cached", or the results of the query being cached. It's a performance optimization; it's a matter of that statement already being prepared, within your session.
By using dynamic SQL, you can control when the statement is prepared (i.e. parsing the SQL text for syntax (statement formation, keywords, etc.), checked for semantics (object names exist, column names exist, user has required privileges, etc.), and preparing an execution plan.
With the static SQL, all of that happens on the first execution, and then MySQL hangs on to the prepared statement.
For performance reasons, we wouldn't want the overhead of a "hard parse" every time a static statement is executed. This is especially true on a function that gets called multiple times, from a SQL statement.
(NOTE: Oracle does the same thing, BUT, Oracle does a good job of marking prepared statements as INVALID whenever a referenced object is altered or dropped.)
MySQL opted not to do that, probably because of the overhead of tracking all the dependencies. And, in the vast majority of cases, that overhead is not required.
I think the lesson here is if you are going to use dynamic SQL to create a table that is going to have DIFFERENT columns in it, you are going to have to use dynamic SQL to query that table.
My recommendation is that you avoid using SELECT *, unless your statement is in complete control of the columns being returned, for example, from an inline view. Otherwise, SQL statements that use SELECT * are fundamentally broken... they may work now, but a change to a table (adding a column for example) will break an application.
Q: Please explain how it is not a bug.
It is not a bug because the SELECT statement in your stored procedure is really just shorthand for what is actually happening.
On the first execution of your procedure, MySQL is doing the parse of your query text, and preparing and executing a statement. Basically, equivalent to:
PREPARE s1 FROM 'SELECT * FROM mydata';
EXECUTE s1;
On the second execution of the procedure, MySQL is simply executing the statement that has been previously prepared. Basically, equivalent to:
EXECUTE s1;
On that second execution, you seem to be expecting MySQL to run the equivalent of:
DEALLOCATE PREPARE s1;
PREPARE s1 FROM 'SELECT * FROM mydata';
EXECUTE s1;
You can make a case that this is what MySQL should be doing on the second execution. You could argue that statements prepared during a previous execution of a procedure should be discarded, and re-parsed and re-prepared on subsequent executions.
It would not be wrong for a DBMS to do this. But there would be, as always, the consideration about the impact on performance.
You could also make a case that MySQL should track all the database objects that a particular prepared statement is dependent on. You could argue that whenever one of those database objects is dropped or altered, MySQL should invalidate all the prepared statements (and all other objects) that depend on the altered or dropped object. Again, it would not be wrong for a DBMS to do this. Some DBMSs (such as Oracle) do this quite well. But again, the developers of the DBMS also take performance into consideration when making these design and implementation decisions.
The bottom line is that MySQL does provide you with a way to make happen what you want to happen. It's just that the syntax in your procedure, what you are expecting to make it happen, doesn't actually make it happen.
first of all it is a temp table so really should not be expected to be there, 2nd - it is dropped
I think you are reading something different into the "TEMPORARY" keyword than is defined in the specification. A TEMPORARY table is really just like a regular table, except that it is visible only to the session that created it, and it will be automatically dropped when the MySQL session ends. (We also note that a TEMPORARY table is not displayed by a SHOW TABLES command, and does not appear in the information_schema views.)
As to which tables (TEMPORARY or otherwise) MySQL should expect "to be there", I don't believe the documentation really addresses that, except noting that when a SQL statement is executed, and that statement references an object that does not exist, MySQL will throw an exception.
The same behavior you observe with a TEMPORARY table, you will also observe with a non-TEMPORARY table. The issue is not related to whether the table is defined as TEMPORARY or not.
where does SELECT * compare to PREPARE s1 FROM SELECT *
Those two forms effectively follow the same code path. The first execution of a static SELECT * is effectively equivalent to:
PREPARE s1 FROM 'SELECT *';
EXECUTE s1;
(Note the absence of a DEALLOCATE statement following the exeuction.) On a subsequent execution, the statement is already prepared, so it's effectively equivalent to:
EXECUTE s1;
This is similar to what would happen if you were coding in PHP mysqli
$s1 = $mysqli->prepare("SELECT * FROM mydata");
$mysqli->execute($s1);
/* rename the columns in the mydata table */
$mysqli->execute($s1);
I understand this is relatively old (+6 months) but I encountered this problem in prepared statements, and the only way I got around it was to concatenate the field names and use a prepared statement that effectively calls "select *" but uses the actual field names. I'm using prepared statements to create a temporary table, and the only standard field is the first one, while the rest causes the caching problem on "Select *".
Select fields we want to use into a temp table
Iterate through table rows of field names, and on each iteration:
set sql01 = concat(sql01,',',sFieldName,''); (just fields) and: set sql02 = concat(sql02,',',sFieldName,' varchar(50) '); (fields + field type only, for create table statement)
create the output table:
set #sql = concat('CREATE TEMPORARY TABLE tOutput(FirstField varchar(50), ',sql02,');'); PREPARE STMT FROM #sql; EXECUTE STMT; DEALLOCATE PREPARE STMT;
At the end:
set #sql = concat('SELECT FirstField,',sql01,' FROM tOutput;'); PREPARE STMT FROM #sql; EXECUTE STMT; DEALLOCATE PREPARE STMT;
I have this query, and I think it talks by itself:
mysql> select id,email from members where email LIKE "%abraham.sustaita#gmail.com%";
+--------+----------------------------+
| id | email |
+--------+----------------------------+
| 272118 | abraham.sustaita#gmail.com |
+--------+----------------------------+
1 row in set (0.69 sec)
mysql> select id,email from members where email = "abraham.sustaita#gmail.com";
Empty set (0.00 sec)
mysql> select id,email from members where id = 272118;
Empty set (0.00 sec)
The data exists, but it returns empty if I use other than LIKE...
When there is such a flagrant impossible sequence of queries, then it's time to think about a table (or index) corruption and to run the Mysql CHECK command.
In that case, running REPAIR TABLE members QUICK did the trick.
If the id is a varchar and the email is a varchar they might have surrounding spaces.