mysql left join takes too long - php

I have the following SQL Query:
SELECT
upd.*,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`
FROM
updates AS upd
LEFT JOIN
subscribers AS sub ON upd.uid=sub.suid
LEFT JOIN
users AS usr ON upd.uid=usr.uid
WHERE
upd.deleted='0' && (upd.uid='118697835834' || sub.uid='118697835834')
GROUP BY upd.id
ORDER BY upd.date DESC
LIMIT 0, 15
where i get all user(118697835834) updates, his profile picture from another table using left join and also all his subscription users updates so can i show them in his newsfeed.
However as the updates get more and more so the query takes more time to load... right now using Codeigniter's Profiler i can see that the query takes 1.3793...
Right now i have created around 18k dummy accounts and subscribed from to me and vice versa so i can test the execution time... the times that i get are tragic considering that i am in localhost...
I also have some indexes where i suppose need more in the users table(username and uid as unique), updates table(update_id as unique and uid as index)
I suppose i am doing something wrong to get so bad results...
EDIT:
Running EXPLAIN EXTENDED result:
Array
(
[0] => stdClass Object
(
[id] => 1
[select_type] => SIMPLE
[table] => upd
[type] => ALL
[possible_keys] => i2
[key] =>
[key_len] =>
[ref] =>
[rows] => 22
[filtered] => 100.00
[Extra] => Using where; Using temporary; Using filesort
)
[1] => stdClass Object
(
[id] => 1
[select_type] => SIMPLE
[table] => sub
[type] => ALL
[possible_keys] =>
[key] =>
[key_len] =>
[ref] =>
[rows] => 18244
[filtered] => 100.00
[Extra] => Using where
)
[2] => stdClass Object
(
[id] => 1
[select_type] => SIMPLE
[table] => usr
[type] => eq_ref
[possible_keys] => uid
[key] => uid
[key_len] => 8
[ref] => site.upd.uid
[rows] => 1
[filtered] => 100.00
[Extra] =>
)
)
EDIT2: SHOW CREATE of Tables
Users table:
CREATE TABLE `users` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`uid` bigint(20) NOT NULL,
`username` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`email` text CHARACTER SET latin1 NOT NULL,
`password` text CHARACTER SET latin1 NOT NULL,
`profile_picture_full` text COLLATE utf8_unicode_ci NOT NULL,
`profile_picture` text COLLATE utf8_unicode_ci NOT NULL,
`date_registered` datetime NOT NULL,
`activated` tinyint(1) NOT NULL,
`closed` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uid` (`uid`),
UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM AUTO_INCREMENT=23521 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Subscribers table:
CREATE TABLE `subscribers` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`sid` bigint(20) NOT NULL,
`uid` bigint(20) NOT NULL,
`suid` bigint(20) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=18255 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Updates table:
CREATE TABLE `updates` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`update_id` bigint(19) NOT NULL,
`uid` bigint(20) NOT NULL,
`type` text COLLATE utf8_unicode_ci NOT NULL,
`update` text COLLATE utf8_unicode_ci NOT NULL,
`date` datetime NOT NULL,
`total_likes` int(11) NOT NULL,
`total_comments` int(11) NOT NULL,
`total_favorites` int(11) NOT NULL,
`category` bigint(20) NOT NULL,
`deleted` tinyint(1) NOT NULL,
`deleted_date` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `i1` (`update_id`),
KEY `i2` (`uid`),
KEY `deleted_index` (`deleted`)
) ENGINE=MyISAM AUTO_INCREMENT=23 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Try this one (without the GROUP BY):
SELECT
upd.*,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`
FROM
updates AS upd
LEFT JOIN
users AS usr
ON upd.uid = usr.uid
WHERE
upd.deleted='0'
AND
( upd.uid='118697835834'
OR EXISTS
( SELECT *
FROM subscribers AS sub
WHERE upd.uid = sub.suid
AND sub.uid = '118697835834'
)
)
ORDER BY upd.date DESC
LIMIT 0, 15
At least the columns that are used in Joins should be indexed: updates.uid, users.uid and subscribers.suid.
I would also add an index on subscribers.uid.

Try:
SELECT
upd.*,
usr.username AS `username`,
usr.profile_picture AS `profile_picture`
FROM
updates AS upd
LEFT JOIN
subscribers AS sub ON upd.uid=sub.suid
LEFT JOIN
users AS usr ON upd.uid=usr.uid
WHERE
upd.deleted=0 and upd.uid in (118697835834,118697835834)
GROUP BY upd.id
ORDER BY upd.date DESC
LIMIT 0, 15
Note that ' has been removed from numeric values and bitwise operators changed to conventional operators.

don't use joins, try this one:
select *,
(select username from users where uid = upd.uid) as username,
(select profile_picture from users where uid = upd.uid) as profile_picture,
from updates as upd
WHERE
upd.deleted='0' && upd.uid='118697835834'
(not tested!)
maybe you have to check if there exists a subscriber in the where-clause with another sub-select.
Another way would be to make a join on sub-selects and not on the whole table. This may increase your performance also.

Shouldn't take too long to run; do you have an index on 'deleted'? What is the 'GROUP BY id' doing? Should it be UID? Can it come out, if ID is in fact just an auto increment, unique ID? (which would be expensive as well as pointless)

I think you'll be best separating this query into a select on the user table and then union those results with the select on the subscribers table.

Related

mysql join query not returning correct values

Currently I have a loop that retrieves data from 2 tables, users and clients, for each row. So the queries are stacking up.
Firstly, is this a bad thing?
I'm looking to display 20 rows per page, so currently that work be about 45 queries.
Here's a list of the queries when I'm displaying only 2 rows:
Database queries
#1
SELECT CID FROM users WHERE Hash = :Hash LIMIT 1;
#2
SELECT start_time,finish_time,dinner_time FROM company WHERE CID = :CID LIMIT 1;
#3
SELECT CID,Access,Hash FROM users WHERE CID = :CID LIMIT 1;
#4
SELECT count(*) FROM jobs WHERE CID = :CID AND ( ( Status="1" ) OR ( Status="2" ) ) AND SUBSTRING(LOWER(`SiteName`), 1, 1) REGEXP '[[:digit:]]';
#5
SELECT * FROM jobs WHERE CID = :CID AND ( ( Status="1" ) OR ( Status="2" ) ) AND SUBSTRING(LOWER(`SiteName`), 1, 1) REGEXP '[[:digit:]]' ORDER BY JID DESC LIMIT 20;
#6
SELECT UID,FirstName,LastName FROM users WHERE CID = :CID AND UID = :UID LIMIT 1;
#7
SELECT ClientID,Name FROM clients WHERE CID = :CID AND ClientID = :ClientID LIMIT 1;
#8
SELECT UID,FirstName,LastName FROM users WHERE CID = :CID AND UID = :UID LIMIT 1;
#9
SELECT ClientID,Name FROM clients WHERE CID = :CID AND ClientID = :ClientID LIMIT 1;
#10
SELECT UID,FirstName,LastName FROM users WHERE CID = :CID AND UID = :UID LIMIT 1;
What I'm thinking is joining the users and clients into one query (6-7 from the list above)
SELECT u.UID, u.FirstName, u.LastName, c.ClientID, c.Name FROM users u INNER JOIN clients c WHERE u.CID = :CID AND c.CID = :CID2 AND u.UID = :UID AND c.ClientID = :ClientID
This is what is returned:
Array
(
[0] => Array
(
[name] => UID
[value] => 1
[type] => 1
)
[1] => Array
(
[name] => ClientID
[value] => 8
[type] => 1
)
[2] => Array
(
[name] => CID
[value] => 1
[type] => 1
)
[3] => Array
(
[name] => CID2
[value] => 1
[type] => 1
)
)
I was expecting is to return like:
Array
(
[UID] => 1
[FirstName] => John
[LastName] => Smith
[ClientID] => 1
[Name] => Client Name
)
Anyone know where I'm going wrong?
Update
clients table
CREATE TABLE IF NOT EXISTS `clients` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`CID` int(11) NOT NULL,
`ClientID` int(11) DEFAULT NULL,
`Name` varchar(100) NOT NULL,
`Clientcontact` varchar(100) NOT NULL,
`Prefix` varchar(20) NOT NULL,
`Email` varchar(50) NOT NULL,
`Phone` varchar(12) NOT NULL,
`Fax` varchar(12) NOT NULL,
`Address1` varchar(100) NOT NULL,
`Address2` varchar(100) NOT NULL,
`Address3` varchar(100) NOT NULL,
`County` varchar(100) NOT NULL,
`Post` varchar(100) NOT NULL,
`Invoicecontact` varchar(100) NOT NULL,
`Invoiceemail` varchar(50) NOT NULL,
`Invoiceaddress1` varchar(100) NOT NULL,
`Invoiceaddress2` varchar(100) NOT NULL,
`Invoiceaddress3` varchar(100) NOT NULL,
`Invoicecounty` varchar(100) NOT NULL,
`Invoicepost` varchar(100) NOT NULL,
`Dateadded` int(10) NOT NULL,
`vat` tinyint(1) DEFAULT NULL,
`vatnumber` int(14) DEFAULT NULL,
`Status` tinyint(1) NOT NULL,
PRIMARY KEY (`ID`)
)
users table
CREATE TABLE IF NOT EXISTS `users` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`CID` int(11) DEFAULT NULL,
`UID` int(11) DEFAULT NULL,
`FirstName` varchar(25) DEFAULT NULL,
`LastName` varchar(25) DEFAULT NULL,
`dob1` varchar(2) DEFAULT NULL,
`dob2` varchar(2) DEFAULT NULL,
`dob3` varchar(4) DEFAULT NULL,
`Email` varchar(50) DEFAULT NULL,
`password_hash` text NOT NULL,
`api_key` varchar(32) NOT NULL,
`api_sync_key` varchar(10) NOT NULL,
`api_sync_word` varchar(10) NOT NULL,
`Hash` varchar(32) DEFAULT NULL,
`start_time` decimal(4,2) DEFAULT NULL,
`end_time` decimal(4,2) DEFAULT NULL,
`dinner_time` decimal(4,2) DEFAULT NULL,
`Phone_A` varchar(15) DEFAULT NULL,
`Phone` varchar(15) DEFAULT NULL,
`MobileNum` varchar(15) DEFAULT NULL,
`WorkNum` varchar(15) DEFAULT NULL,
`Emg` varchar(50) DEFAULT NULL,
`EmgNum` varchar(15) DEFAULT NULL,
`Address1` varchar(100) DEFAULT NULL,
`Address2` varchar(100) DEFAULT NULL,
`Address3` varchar(100) DEFAULT NULL,
`County` varchar(100) DEFAULT NULL,
`Post` varchar(100) DEFAULT NULL,
`DateJoined` varchar(30) DEFAULT NULL,
`LastLogged` int(11) DEFAULT NULL,
`DateLeft` int(11) DEFAULT NULL,
`Contract` int(3) DEFAULT NULL,
`Pay` int(3) DEFAULT NULL,
`Position` int(3) DEFAULT NULL,
`Active` varchar(255) DEFAULT NULL,
`Access` tinyint(2) DEFAULT NULL,
PRIMARY KEY (`ID`)
)
If your table structure is as follow then you should write your query as I have written.
TABLE NAME: Users ( Your Primary Table )
UID PK
FirstName
LastName
TABLE NAME: Clients
ClientID PK
NAME
UID FK
SELECT u.UID AS UID,
u.FirstName AS FirstName,
u.LastName AS LastName,
c.ClientID AS ClientID,
c.Name AS NAME
FROM users AS u
LEFT JOIN clients AS c ON u.UID = c.UID
WHERE u.UID = :UID;

MYSQL: join multiple tables - replace multiple userID's with user names

I have two tables, one with all the user data and one with some orders.
the order is always for one user, but made from another user (user can't order for his self)
in the order table the editor and the user are only stored with their id corresponding to the user table.
here the shortened tables:
`orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL,
`editor_id` int(10) NOT NULL,
`reason` char(200) COLLATE utf8_unicode_ci NOT NULL,
`amount` decimal(10,2) NOT NULL
)
`users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` char(250) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`password` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`email` varchar(250) COLLATE utf8_unicode_ci NOT NULL DEFAULT ''
)
i want to query one of the orders, and get the user_id replaced with user_name and editor_id also replaced with the correct name from the users table.
this is what a normal orders query result looks like:
[0] => Array
(
[id] => 714
[user_id] => 97
[editor_id] => 45
[reason] => Ausgaben Regale 28.09.13
[amount] => 150.00
)
and this is what i want:
[0] => Array
(
[id] => 714
[user_id] => 97
[editor_id] => 45
[user_name] => the user name
[editor_name] => the editor name
[reason] => Ausgaben Regale 28.09.13
[amount] => 150.00
)
I tried so many different joins, but all without success, would love to get the hint pointing me to the right direction.
This?
SELECT o.id, o.user_id, o.editor_id, u1.name as user_name, u2.name as editor_name,
o.reason, o.amount
FROM orders o
INNER JOIN users u1 ON o.user_id = u1.id
INNER JOIN users u2 ON o.editor_id = u2.id
WHERE o.id = "requested order id"
SELECT orders.*,user.name as user_name,editor.name as editor_name FROM orders
inner join users user on orders.user_id=user.id
inner join users editor on orders.editor_id=editor.id where orders.id="requested id"

Modify SQL to include extra table

How would I get the banner name? If you look at the DB below you will see that this bring back everything apart from the actual banner.name?
Also I presume that it should check that the banner status to check it is enabled.
BEFORE:
SELECT *
FROM banner_image bi
LEFT JOIN banner_image_description bid ON (bi.banner_image_id = bid.banner_image_id)
WHERE
bi.banner_id = '".$banner_id."'
AND bid.language_id = '".$this->config->get('config_language_id')."'
Array (
[0] => Array (
[banner_image_id] => 1
[banner_id] => 1
[link] =>
[image] => data/banners/test.jpg
[language_id] => 1
[title] => Test banner
)
)
AFTER:
SELECT
bi.*,
b.name
FROM
banner b,
banner_image bi
LEFT JOIN banner_image_description bid ON (bi.banner_image_id = bid.banner_image_id)
WHERE
b.banner_id = '".$banner_id."'
AND bi.banner_id = '".$banner_id."'
AND bid.language_id = '".$this->config->get('config_language_id')."'
Array (
[0] => Array (
[banner_image_id] => 1
[banner_id] => 1
[link] =>
[image] => data/banners/test.jpg
[name] => Banner heading
)
)
DB Structure:
CREATE TABLE IF NOT EXISTS `banner` (
`banner_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) COLLATE utf8_bin NOT NULL,
`status` tinyint(1) NOT NULL,
PRIMARY KEY (`banner_id`)
);
CREATE TABLE IF NOT EXISTS `banner_image` (
`banner_image_id` int(11) NOT NULL AUTO_INCREMENT,
`banner_id` int(11) NOT NULL,
`link` varchar(255) COLLATE utf8_bin NOT NULL,
`image` varchar(255) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`banner_image_id`)
);
CREATE TABLE IF NOT EXISTS `banner_image_description` (
`banner_image_id` int(11) NOT NULL,
`language_id` int(11) NOT NULL,
`banner_id` int(11) NOT NULL,
`title` varchar(64) COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`banner_image_id`,`language_id`)
);
I think this will do what you want:
SELECT *
FROM
banner b
INNER JOIN banner_image bi ON b.banner_id = bi.banner_id
INNER JOIN banner_image_description bid ON bi.banner_image_id = bid.banner_image_id
WHERE
b.banner_id = '". $banner_id ."'
AND b.status = TRUE
AND bid.language_id = '". $this->config->get('config_language_id') ."'
I would avoid using SELECT * and instead, explicitly list out each column you actually want to fetch.
One reason I think you were having trouble is that you used a comma (implicit join) to join in the banner table, but you didn't specify a join condition. You would have needed a condition in your WHERE clause like b.banner_id = bi.banner_id. But it would be better to use explicit INNER JOIN syntax.
I don't see a reason for using a LEFT JOIN instead of an INNER JOIN in this query. In the WHERE clause, you specify a condition that must be met in the banner_image_description table in order for a row to be returned. If there is no corresponding row in that table (which is the purpose of a LEFT JOIN), then there will be no row returned. So I switched them to INNER JOIN.

How to merge two tables MySQL-PHP with date sorting

I want to merge the results of two tables in to one.
Please refer the following tables :
Data from microblog table as Row array
Array ( [ID] => 46 [userID] => 1 [userNAME] => user [blog_content] => HAI DEAR [page_name] => honda [page_ID] => 31 [post_time] => 2011-10-18 11:06:54 )
Data from Page_review table as Row array
Array ( [page_review_id] => 5 [page_id] => 31 [page_review_by_id] => 31 [page_review_by_username] => user [page_review_time] => 2011-10-18 11:43:34 [page_review_content] => hai )
Table Microblog MySQL query:
DROP TABLE IF EXISTS `featurezme_store`.`microblog`;
CREATE TABLE `featurezme_store`.`microblog` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`userID` int(10) unsigned NOT NULL,
`userNAME` varchar(45) NOT NULL,
`blog_content` text NOT NULL,
`page_name` varchar(45) NOT NULL,
`page_ID` int(10) unsigned NOT NULL,
`post_time` datetime NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=48 DEFAULT CHARSET=latin1;
Table page_review
DROP TABLE IF EXISTS `featurezme_store`.`page_review`;
CREATE TABLE `featurezme_store`.`page_review` (
`page_review_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`page_id` int(10) unsigned NOT NULL,
`page_review_by_id` int(10) unsigned NOT NULL,
`page_review_by_username` varchar(145) NOT NULL,
`page_review_time` datetime NOT NULL,
`page_review_content` varchar(555) NOT NULL,
PRIMARY KEY (`page_review_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
the table Microblog is used to store blog posts & page_review is used to store reviews about pages[Microblog's are in pages].
My requirement is i want to show Blogposts & page reviews sorted by Date [post_time in Microblog & page_review_time on page_review].
how can i do this ? please help me.
Okay I have updated my answear, you can use union as you wanted.
Just have the same number of fields and because the results are placed the one unde the other use fields that make sense to be the one under the other. This example will bring all blogs and reviews created by a specific user (if page_review_by_id actually refers to the user id) and related to a specific page.
(
SELECT
`microblog`.`userID`,
`microblog`.`blog_content` as `blog or review`,
`microblog`.`post_time`,
`microblog`.`page_id`
from `microblog`
where `microblog`.`page_id`='1' and `microblog`.`userID`='1'
)
union
(
SELECT
`page_review`.`page_review_by_id`,
`page_review`.`page_review_content`,
`page_review`.`page_review_time`,
`page_review`.`page_id`
from `page_review`
where `page_review`.`page_id`='1' and `page_review`.`page_review_by_id`='1'
)
======== Edit== Suggesting a schema with foreign keys ================
Because I don't see any foreign keys in your schema if I could suggest optionaly a schema that applies foreign keys I present one below.
These rules are supported by this schema:
Blogs belong to the site and not to the user so there is not on delete cascade applied.
Blogs are created by users and a foreign key is applied so when a user id is inserted the consistency is assured through the foreign key.
The same goes for the page, a foreign key is applid without on delte cascade.
The same goes for the reviews table
If a user or page is deleted no child row is deleted
/********Create ***** ***/
CREATE TABLE user (
user_id int unsigned NOT NULL AUTO_INCREMENT,
username varchar(16) NOT NULL,
userpassword BLOB,
PRIMARY KEY (user_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE page (
page_id mediumint unsigned NOT NULL AUTO_INCREMENT,
title varchar(55) NOT NULL,
PRIMARY KEY (page_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE microblog (
blog_id int unsigned NOT NULL AUTO_INCREMENT,
blog_content text NOT NULL,
date_created datetime NOT NULL,
author_id int unsigned NOT NULL,
page_id mediumint unsigned NOT NULL,
PRIMARY KEY (blog_id),
CONSTRAINT blogfk1 FOREIGN KEY (author_id)
REFERENCES user (user_id),
/NO ON DELETE CASCADE/
CONSTRAINT blogfk2 FOREIGN KEY (page_id)
REFERENCES page (page_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE page_review (
review_id int unsigned NOT NULL AUTO_INCREMENT,
review_content varchar(555) NOT NULL,
date_created datetime NOT NULL,
author_id int unsigned NOT NULL,
page_id mediumint unsigned NOT NULL,
PRIMARY KEY (review_id),
CONSTRAINT reviewfk1 FOREIGN KEY (author_id)
REFERENCES user (user_id),
/NO ON DELETE CASCADE/
CONSTRAINT reviewfk2 FOREIGN KEY (page_id)
REFERENCES page (page_id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/************** ******/
/** ***Insertions*** **/
INSERT INTO user ( username,userpassword)
VALUES ('username11', AES_ENCRYPT('password1',
'encription_key') ),
('username22', AES_ENCRYPT('password2',
'encription_key') );
INSERT INTO page ( title) VALUES
('title1'),('title2');
INSERT INTO microblog (blog_content,date_created,
author_id,page_id) VALUES
('blogcontent1','2011-2-2 12:00','1','1'),
('blogcontent2','2011-2-2 12:00','2','2');
INSERT INTO page_review (review_content,
date_created,author_id,page_id) VALUES
('reviewcontent1','2011-2-2 12:00','1','1'),
('reviewcontent2','2011-2-2 12:00','2','2');
/***** *******/
/******* Queries *** /
/Help on Identifing a user/
SELECT username
FROM user WHERE username ='username22'
and userpassword=AES_ENCRYPT('password2','encription_key')
(
SELECT
microblog.blog_content as blog or content,
microblog.date_created,
microblog.author_id,
microblog.page_id
from microblog
where microblog.author_id='1' and microblog.page_id='1'
)
union
(
SELECT
page_review.review_content,
page_review.date_created,
page_review.author_id,
page_review.page_id
from page_review
where page_review.author_id='1' and page_review.page_id='1'
)

MYSQL PDO return type strange conversion

I have the following table definition in MYSQL
CREATE TABLE IF NOT EXISTS `test_cases` (
`id` int(10) unsigned NOT NULL auto_increment,
`exercise_id` int(10) unsigned NOT NULL,
`author_id` int(10) unsigned NOT NULL,
`input_1_value` varchar(255) default NULL,
`input_2_value` varchar(255) default NULL,
`input_3_value` varchar(255) default NULL,
`input_4_value` varchar(255) default NULL,
`input_5_value` varchar(255) default NULL,
`output_value` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `test_cases_ibfk_1` (`exercise_id`),
KEY `author_id` (`author_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3218 ;
I have the following entry into this table
INSERT INTO `test_cases` (`id`, `exercise_id`, `author_id`, `input_1_value`, `input_2_value`, `input_3_value`, `input_4_value`, `input_5_value`, `output_value`) VALUES
(560, 145, 496, '0', NULL, NULL, NULL, NULL, '0')
I have the following query to get the above row from the table
SELECT id, exercise_id, author_id, input_1_value, input_2_value, input_3_value, input_4_value, input_5_value, output_value FROM test_cases WHERE exercise_id=145
I'm interested in, and having problems with, the value in input_1_value. Running the query in phpMyAdmin will return the value as '0', which is as expected. However running the following php script returns the value as 'true' which is completely left field and leaving me and my project supervisor stumped. The php script is below...
$db = DBCxn::getCxn();
$sql = "SELECT id, exercise_id, author_id, input_1_value, input_2_value, input_3_value, input_4_value, input_5_value, output_value FROM test_cases WHERE exercise_id=:exid";
$st=$db->prepare($sql);
$st->bindParam(":exid", $exerciseId, PDO::PARAM_INT); // $exerciseID == 145
$st->execute();
$row = $st->fetch(); // default fetch mode is PDO::FETCH_BOTH
echo $row['input_1_value'];
this echos 'true'!!!! why??? why does it not print '0'???
for even more information using print_r($row); I get the following output
Array ( [id] => 560 [0] => 560 [exercise_id] => 145 [1] => 145 [author_id] => 496 [2] => 496 [input_1_value] => true [3] => true [input_2_value] => [4] => [input_3_value] => [5] => [input_4_value] => [6] => [input_5_value] => [7] => [output_value] => true [8] => true )
Note output_value is also returned as 'true' when it should be '0'.
Does anyone know what is going on here? Any help is appreciated. GREATLY appreciated.
Try setting the constant PDO::ATTR_STRINGIFY_FETCHES to true.
Take a look at http://php.net/manual/en/pdo.setattribute.php, see if it helps.

Categories