Mysql update joins? - mysql

Currently I am updating my different tables like so
$q = $dbc -> prepare("UPDATE boardposts SET lastPosterID = ?, postOrder = NOW() WHERE postID = ?");
$q -> execute(array($user['id'], $_GET['view']));
$q = $dbc -> prepare("UPDATE accounts SET msgBoardPosts = msgBoardPosts+1 WHERE id = ?");
$q -> execute(array($user['id']));
Is it possible to put these kinda update in one query?

Yes It is possible, Something like:
UPDATE boardposts AS bs
left join accounts AS a on bs.AccountId = bs.lastPosterId
set bs.lastPosterId = ?, bs.postOrder = NOW(),
a.msgBoardPosts = msBoardPosts + 1
WHERE bs.postId = ?,
a.id = ?
I didn't now the structure of your two tables but this is the basic idea see the syntax of UPdate:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET....
The table_references clause lists the tables involved in the join. Its syntax is described JOIN Syntax.

Related

Cascade delete in many-to-many tables

Assume a set of mailing lists in which individuals may be members of more than one list. I've set up a join table:
members -> members2lists <- lists
If the user wants to remove a member from one list only, it would seem necessary only to delete the appropriate row in the members2lists table. But how do I specify the cascading so as not to leave them as an orphan if they're a member of only one list? In other words, how do I delete a member if and only if they are a member of solely the list I'm removing them from?
I'm using PHP and mySQL with InnoDB tables.
Thanks David for your response. I've solved the problem this way (I hope the first two functions are self-expanatory):
$memberID = getIDFromMembers($pdo, $email);
$currListID = getIDFromList($pdo, $listname);
// remove record from join table
$sql = 'DELETE FROM `members2lists` WHERE `member_fk` = :member AND `list_fk` = :list';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':member', $memberID);
$stmt->bindParam(':list', $currListID);
$stmt->execute();
// check if another record exists in the join table for the same member
$sql = 'SELECT `member_fk` FROM `members2lists` WHERE `member_fk` = :member';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':member', $memberID);
$stmt->execute();
$row = $stmt->fetch();
if($row === false)
{
// there isn't, the member is an orphan, so delete
$sql = 'DELETE FROM `members` WHERE `member_email` = :email';
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':email', $email);
$stmt->execute();
}
I'd be glad of comments from members about ways to improve this code!

Mysql on duplicate update not working?

movie_title is a unique column. I want to update columns on duplicate. There are no errors in the query.
foreach($array['data'] as $row) {
$movie_title = $row[0];
$time_published = date("Y-m-d H:i:s",strtotime($row[2]));
$language = $row[3];
$views = $row[4];
$active = $row[6];
$type = $row[7];
$checked = $row[8];
$category = $row[9];
$rating = $row[10];
$subtitle = $row[12];
$visitor_views = $row[18];
if($visitor_views!=0) {
$view_array[] = $visitor_views;
}
$movie_title = explode("-",$movie_title);
$movie_title = trim($movie_title[0]);
$wpdb->query($wpdb->prepare("INSERT INTO movies (movie_title,time_published,language,views,visitor_views,active,type,checked,category,rating,subtitle) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ON DUPLICATE KEY UPDATE active=active,category=category,views=views,visitor_views=visitor_views,checked=checked,subtitle=subtitle,rating=rating,type=type,language=language",
$movie_title,$time_published,$language,$views,$visitor_views,$active,$type,$checked,$category,$rating,$subtitle));
}
This is how the query looks
INSERT INTO movies (movie_title,time_published,language,views,visitor_views,active,
type,checked,category,rating,subtitle)
VALUES
('Bodyguard','2016-12-17 06:54:26','1','2091','15',
'1','0','0','Feature Film ','3.66','Bodyguard.vtt')
ON DUPLICATE KEY UPDATE
active=active,category=category,views=views,visitor_views=visitor_views,
checked=checked,subtitle=subtitle,rating=rating,type=type,language=language
Why aren't any of the columns being updated?
Not sure if this solves the issues but perhaps it should be something like this:
ON DUPLICATE KEY UPDATE active = VALUES(active), category = VALUES(category)..
You need to use col_name = VALUES(col_name), otherwise you are just saying "set x = x".
...
ON DUPLICATE KEY UPDATE
active=VALUES(active),category=VALUES(category),views=VALUES(views),...

Updating Multiple Column on MySQL

I want to update members_roosevelt table ACCOUNT column starting with 3000+ value I also want to update ACCOUNT column on loan_roosevelt table that is related to my member_roosevelt. What's wrong with my query? Thank you!
$query1 = "SELECT ACCOUNT
FROM
`members_roosevelt`";
$result_q1 = $link->query($query1) or die($link->error);
while ($obj = $result_q1->fetch_object()) {
$members[] = $obj->ACCOUNT;
}
$ids = implode(',', $members);
$sql = "UPDATE `members_roosevelt` as `memb`
JOIN `loan_roosevelt` as `loan`
ON `memb`.`ACCOUNT` = `loan`.`ACCOUNT`
SET
(`memb`.`ACCOUNT`,
`loan`.`ACCOUNT`) = CASE ACCOUNT";
foreach ($members as $id => $ordinal) {
$sql .= sprintf("WHEN %d THEN %d ", $ordinal, (3000+$id));
}
$sql .= "END WHERE memb.ACCOUNT IN ($ids)";
$link->query($sql) or die($link->error);
SET (`memb`.`ACCOUNT`, `loan`.`ACCOUNT`) = CASE ACCOUNT...
This is simply not part of SQL syntax. You can't set two columns at a time like this. The left side of an assignment operator must be one column.
A better solution is to use a session variable.
SET #acct = 3000;
UPDATE members_roosevelt as memb
JOIN loan_roosevelt as loan
ON memb.ACCOUNT = loan.ACCOUNT
SET memb.ACCOUNT = (#acct:=#acct+1),
loan.ACCOUNT = (#acct);
This way you don't have to run the SELECT query at all, and you don't have to create a huge UPDATE statement with potentially thousands of WHEN clauses.
Demo: SQLFiddle

SQL UPDATE Not Updating

After uploading a csv file, I am trying to insert its contents into my database table. I have this query:
$connect = mysql_connect("localhost","root","");
mysql_select_db("dbtest",$connect);
//get the file
$handle = fopen($filename,"r");
do {
if (isset($data[0])) {
$data0 = mysql_real_escape_string($data[0]); //rcode
$data1 = mysql_real_escape_string($data[1]); //pcode
$data2 = mysql_real_escape_string($data[2]); //mcode
$data3 = mysql_real_escape_string($data[3]); //bcode
$data4 = mysql_real_escape_string($data[4]); //ecode
$data5 = mysql_real_escape_string($data[5]); //filetype
$data6 = mysql_real_escape_string($data[6]); //rec_count
$data7 = mysql_real_escape_string($data[7]); //gen_count
$data8 = mysql_real_escape_string($data[8]); //qc_count
$data9 = mysql_real_escape_string($data[9]); //be_count
$data10 = mysql_real_escape_string($data[10]); //trn_count
$query = "INSERT INTO tbltest(rcode,pcode,mcode,bcode,ecode,filetype,rec_count,
gen_count,qc_count,be_count,trn_count) VALUES ('$data0','$data1','$data2',
'$data3', '$data4', '$data5', '$data6', '$data7', '$data8', '$data9', '$data10')
ON DUPLICATE KEY UPDATE rec_count=values(rec_count),gen_count=values(gen_count),
qc_count=values(qc_count), be_count=values(be_count), trn_count=values(trn_count)";
mysql_query ($query,$connect) ;
}
} while ($data = fgetcsv($handle,1000,"|"));
And it's working neatly but then as the database was re-structured, I just then need to update the database table as rcode to filetype has values already and I just need to insert values of rec_count to trn_count. So my first query INSERT INTO ... ON DUPLICATE KEY UPDATE has been change to UPDATE only. And so I did this:
$query = "UPDATE tbltest SET (rec_count='$data6', gen_count = '$data7',
qc_count = '$data8', be_count = '$data9', trn_count= '$data10') WHERE
(rcode = '$data0', pcode = '$data1', mcode = '$data2', bcode = '$data3',
ecode = '$data4', filetype = '$data5')";
My problem now is that, my UPDATE seems to be not working as it doesn't update the database table. Bu when I did this;
$query = "UPDATE tbltest SET rcode = '5'";
The database is being updated. When I tried echo $query;, the echo responds the correct data (from the csv). I just cannot figure why it doesn't insert these data into the database. Kindly help. Thanks
Your SQL syntax is incorrect. The statement should read something like
UPDATE tbltest
SET rec_count='...', gen_count = '...', ...
WHERE rcode = '...' AND pcode = '...' AND ...
See MySQL UPDATE syntax.

sql update statement with from clause for validation?

I have an update operation that I perform on multiple users at once (the value stays the same). Is it possible to join tables to an update statement for reasons of validation?
For instance, here is my statement at the moment :
$user_set = array(1, 5, 10, 15, .....)
//update 'changed' status for ALL selected users at once
$stmt = $db->prepare("
UPDATE users
SET changed = ?
WHERE user_id IN(". implode(', ', array_fill(1,count($user_set),'?')) .")
");
array_unshift($user_set, 1);
$stmt->execute($user_set);
In a perfect scenario I would like to join one table (computers) to the users table to validate account ownership and if this update is 'valid' and should occur or not.
I found out earlier I can do EXACTLY that with DELETE, but can it be done with UPDATE as well? Example delete using validation I want :
$selected = array(1, 5, 10, 15, .....)
$stmt = $db->prepare("
DELETE del_table.*
FROM some_table as del_table
LEFT JOIN
users
on users.user_id = del_table.user_id
LEFT JOIN
computers
on computers.computer_id = users.computer_id
WHERE computers.account_id = ? AND del_table.activity_id IN(". implode(', ', array_fill(1,count($selected),'?')) .")
");
// use selected array and prepend other data into the array so binding and execute work in order
array_unshift($selected, $_SESSION['user']['account_id']);
$stmt->execute($selected);
EDIT (SOLUTION) :
Thanks Alex... it works!
$selected = array(5,10,12,13);
$stmt = $db->prepare("
UPDATE users
INNER JOIN computers
on computers.computer_id = users.computer_id
SET changed = ?
WHERE computers.account_id = ? AND users.user_id IN(". implode(', ', array_fill(1,count($selected),'?')) .")
");
array_unshift($selected, 1, $_SESSION['user']['account_id']);
$stmt->execute($selected);
Yes, you can, as documented here under the multi-table syntax section.
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
You just need to make sure you order the statements correctly.
UPDATE my_table
INNER JOIN other_table
ON my_table.col2 = othertable.col2
SET my_table.col = 'foo'
WHERE other_table.col = 'bar'
try this
$stmt = $db->prepare("
UPDATE users
SET changed = ?
from users
JOIN computers on computers.computer_id = users.computer_id
WHERE user_id IN(". implode(', ', array_fill(1,count($user_set),'?')) .")
");