PDO MySQL insert multiple rows using select - mysql

I have a table for storing people following others and another one for storing who has a certain book.
This is what I can do:
List users who follow $userid
$bookid = '000016';
$userid = '0000000000000156';
try {
$stmt = $conn->prepare("SELECT FOLLOW.USER_ID FROM FOLLOW WHERE FOLLOW.FOLLOW_ID = ?");
$stmt -> execute(array($userid));
while($row = $stmt->fetchAll(PDO::FETCH_ASSOC)) {
$output[] = $row;
$response["success"] = 1;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response["success"] = 0;
}
List users who has $bookid
try {
$stmt = $conn->prepare("SELECT USERS_BOOKS.USERID FROM USERS_BOOKS WHERE USERS_BOOKS.BOOKID = ?");
$stmt -> execute(array($bookid));
while($row = $stmt->fetchAll(PDO::FETCH_ASSOC)) {
$output2[] = $row;
$response["success"] = 1;
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
$response["success"] = 0;
}
Now I want to insert those into a new table who follow $userid and has $bookid. This is what I tried with different versions:
try {
$stmt = $conn->prepare("INSERT INTO NOTI_COMPLETE2 (USERID_OWNER, USERID_COMPLETER, BOOKID)
SELECT FOLLOW.USERID FROM FOLLOW
LEFT JOIN USERS_BOOKS ON USERS_BOOKS.USERID = FOLLOW.USERID
WHERE FOLLOW.FOLLOW_ID = ? AND USERS_BOOKS.BOOKID = ?, ?, ?");
$query_params = array($userid, $bookid, $userid, $bookid);
$stmt->execute($query_params);
$response["success"] = 1;
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
So the result should look like this
ID, USERID_OWNER, USERID_COMPLETER, BOOKID
01, 000000000001, 0000000000000156, 000016
01, 000000000011, 0000000000000156, 000016
01, 000000000078, 0000000000000156, 000016
01, 000000000105, 0000000000000156, 000016
Meaning the table includes those USERID_OWNERs who follow USERID_COMPLETER and have BOOKID.
This throws an error (that's irrelevant I guess, because who knows how to do this, sees the problem).

You missed VALUES ('','','') and it should have exactly 3 columns fetched from your SELECT statement,
As I am not sure about USERID_COMPLETER. You have to place the exact 'table-name'.'column-name' there
INSERT INTO NOTI_COMPLETE2 (`USERID_OWNER`, `USERID_COMPLETER`, `BOOKID`)
VALUES ( SELECT FOLLOW.USERID, FOLLOW.FOLLOW_ID, USERS_BOOKS.BOOKID FROM FOLLOW
LEFT JOIN USERS_BOOKS ON USERS_BOOKS.USERID = FOLLOW.USERID
WHERE FOLLOW.FOLLOW_ID = ? AND USERS_BOOKS.BOOKID = ?);

try {
$stmt = $conn->prepare("INSERT INTO NOTI_COMPLETE2 (USERID_OWNER, USERID_COMPLETER, BOOKID)
SELECT FOLLOW.USER_ID, ?, ?, ? FROM FOLLOW
LEFT JOIN USERS_BOOKS ON USERS_BOOKS.USERID = FOLLOW.USER_ID
WHERE FOLLOW.FOLLOW_ID = ? AND USERS_BOOKS.BOOKID = ?");
$query_params = array($userid, $bookid, $userid, $bookid);
$stmt->execute($query_params);
$response["success"] = 1;
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}

Related

Mysql - Get data from two tables

I have two tables webadstats and webstatsclick and i want to make below query from these two tables.
$sql2 = "SELECT
count(*) as 'impressions',
unix_timestamp(date(from_unixtime(A.time))) as 'timestamp',
COUNT(B.click) as 'clickss'
FROM `webadstats` as A
LEFT JOIN `webstatsclick` as B
ON A.pubadhash = B.pubadhash
WHERE A.pubadhash='$pubadhash'
GROUP BY date(from_unixtime(A.time))";
$result2 = mysqli_query($conn, $sql2);
if (mysqli_num_rows($result2)>0) {
while($row = mysqli_fetch_assoc($result2)) {
$impressions[] = $row['impressions'];
$clicksall[] = $row['clickss'];
$timestamp[] = $row['timestamp'];
}
for($i=0; $i<count($clicksall); $i++){
$str .= $timestamp[$i] . '||' . $impressions[$i] . '||' . $clicksall[$i] ."\n";
}
}
echo $str;
But the problem is that this query is generating same values for both the variables impressions and clickss out of which value of impressions variable is correct.
1542434400||1270||1270
1542520800||1800||1800
1542607200||1745||1745
1542693600||1805||1805
1542780000||1615||1615
1542866400||1740||1740
1542952800||1740||1740
1543039200||1830||1830
1543125600||1830||1830
1543212000||1615||1615
1543298400||1880||1880
1543384800||2125||2125
1543471200||1530||1530
1543557600||1370||1370
1543644000||120||120
My both the DB structure is
webadstats db
webadstats db
webstatsclick db
webstatsclick db
Kindly help me where i am wrong.
Let's go back to the two query approach. The problem is, we've been trying to use JOIN on pubadhash but also WHERE with pubadhash, so the values get multiplied.
$sql2 = "SELECT
count(*) as 'impressions',
unix_timestamp(date(from_unixtime(time))) as 'timestamp'
FROM `webadstats`
WHERE pubadhash='$pubadhash'
GROUP BY date(from_unixtime(time))";
$sql3 = "SELECT
count(*) as 'clickss',
unix_timestamp(date(from_unixtime(time))) as 'timestamp'
FROM `webstatsclick`
WHERE pubadhash='$pubadhash'
GROUP BY date(from_unixtime(time))";
$result2 = mysqli_query($conn, $sql2);
if (mysqli_num_rows($result2)>0) {
while($row = mysqli_fetch_assoc($result2)) {
$arr[$row['timestamp']]['impressions'] = $row['impressions'];
$arr[$row['timestamp']]['timestamp'] = $row['timestamp'];
$arr[$row['timestamp']]['clickss'] = 0;
}
$result3 = mysqli_query($conn, $sql3);
if (mysqli_num_rows($result3)>0) {
while($row = mysqli_fetch_assoc($result3)) {
$arr[$row['timestamp']]['clickss'] = $row['clickss'];
}
}
foreach($arr as $clicks){
$str .= $clicks['timestamp'] . '||' . $clicks['impressions'] . '||' . $clicks['clickss'] ."\n";
}
}
echo $str;

SQL update not committed

I am having a weird issue but I do not understand what is happening. I amcreated a function to update up to three columns (end_plan_date, balance and server) in a table (user) and 2 inserts in another table.
For some reason, my last update (column server of the user table) is not committed ($query = mysql_query("UPDATE user SET server='$serv' WHERE email='$subemail'");) unless I give a value for at leat one of the two other values ($subamt or $subday).
Do you know why this query is not updating the user table with the server value I parsed?
function addBalance($subemail, $subamt,$subday,$userid,$serv) {
$q = "SELECT * FROM user WHERE email = '$subemail'";
$result = mysql_query($q, $this->connection);
$dbarray = mysql_fetch_array($result);
$endplan_date=$dbarray['end_plan_date'];
if($subday >0){
if($endplan_date=="0000-00-00" ){
$endplan_date = date('Y-m-d');
$new_endplan_date = date('Y-m-d',strtotime($endplan_date . "+".$subday." days"));
}else{
$new_endplan_date = date('Y-m-d',strtotime($endplan_date . "+".$subday." days"));
}
$query = mysql_query("UPDATE user SET end_plan_date='$new_endplan_date' WHERE email='$subemail'");
$recdate=gmdate('Y-m-d H:i:s');
$q = "INSERT INTO com_gest(recdate,userid,type,recvalue) VALUES ('$recdate','$userid','Plan Date','$subday')";
mysql_query($q, $this->connection);
}
if($subamt >0){
$query = mysql_query("UPDATE user SET balance=balance+".$subamt." WHERE email='$subemail'");
$recdate=gmdate('Y-m-d H:i:s');
$q = "INSERT INTO com_gest(recdate,userid,type,recvalue) VALUES '$recdate','$userid','Balance','$subamt')";
mysql_query($q, $this->connection);
}
$query = mysql_query("UPDATE user SET server='$serv' WHERE email='$subemail'");
return 0;
}
In your code u can't get directly this
$endplan_date=$dbarray['end_plan_date'];
for fetching this variable u have to use while loop like
while($dbarray = mysql_fetch_array($result);) {
$endplan_date=$dbarray['end_plan_date'];
}
There was an issue when calling this function.

how to write code in order to update stock after we sell a product

I have written following code for my sales_invoice.php
if(isset($_POST['submit1'])){
// $cat_array = $_POST['category_name'];
// $qua_array = $_POST['quantity'];
//$mrp_array = $_POST['mrp'];
//$vat_array = $_POST['vat'];
// print_r($_POST);
if(!empty($_POST['item_name']) && is_array($_POST['item_name'])){
$name_array =$_POST['item_name'];
//print_r($name_array);
for($j=0; $j< count($name_array);$j++){
$name = mysql_real_escape_string($name_array[$j]);
//echo $name;
//$n = explode('/',$name);
$sql = "select quantity from purchase_stock where item_name = '$name'";
// echo $sql;
$res = mysql_query($sql) or die(mysql_error());
$num_rows = mysql_num_rows($res);
if($num_rows <=0){
echo "<b>not in stock</b>";
exit();
}
else
continue;
}
}
$sql = "insert into material_inv set order_date='$new_date', due_date='$new_date1', dealer='".$_POST['dealer']."', customer='".$_POST['customer']."'";
// echo $sql;
$res = mysql_query($sql) or die(mysql_error());
if($res == true){
echo "sales invoice created";
}
else
{
echo "error";
}
$myid = mysql_insert_id();
$sales_id = $myid;
//display_item();
// print_r($_POST);
if (!empty($_POST['category_name']) && !empty($_POST['item_name']) && !empty($_POST['quantity']) && !empty($_POST['mrp']) && !empty($_POST['vat']) &&
is_array($_POST['category_name']) && is_array($_POST['item_name']) && is_array($_POST['quantity']) && is_array($_POST['mrp']) && is_array($_POST['vat'])){
// echo 'start';
$name_array = $_POST['item_name'];
$cat_array = $_POST['category_name'];
$qua_array = $_POST['quantity'];
$mrp_array = $_POST['mrp'];
$vat_array = $_POST['vat'];
//print_r($mrp_array);
for ($i = 0; $i < count($name_array); $i++) {
$name = mysql_real_escape_string($name_array[$i]);
$cat = mysql_real_escape_string($cat_array[$i]);
$q = mysql_real_escape_string($qua_array[$i]);
$mrp = mysql_real_escape_string($mrp_array[$i]);
//echo $mrp;
$vat = mysql_real_escape_string($vat_array[$i]);
// mysql_query("INSERT INTO users (name, age) VALUES ('$name', '$age')");
$sql ="Insert into material_items SET category_name='$cat', item_name='$name', quantity='$q',
mrp='$mrp', vat='$vat', inv_id ='$sales_id'";
// echo $sql;
$res = mysql_query($sql) or die(mysql_error());
$sql1 = "Update stock set quantity=quantity -'$q' where item_name='$name'";
$res1 = mysql_query($sql1) or die(mysql_error());
echo "stock updated and invoice created";
}
}
}
I have first checked if item is present in purchase_stock table. (items are inserted in purchase_stock table after a purchase order is created). Then i insert in the sales table quantity which is sold. And then I write query to update stock table.
My question is do I write a insert query for stock table if no items are initially present there? Is it logically correct? Or should I keep same stock table to update quantity and items after purchase and sales transactions?
Here is an example of a stored procedure syntax
DELIMITER //
CREATE PROCEDURE GetProduct(IN param_ProductID INT)
BEGIN
SELECT *
FROM Products
WHERE ProductID = param_ProductID;
END //
DELIMITER ;
and this is how you call it from your php:
$mysqli->query("CALL GetProduct(".$param_ProductID.")");
regarding your question about inserting the the product,
you need to perform an UPSERT (insert if not exists and update if exists)
here is an example how to do it:
PHP / MySQL : Insert if doesnt exist else update
shimon :)

Mysql / PDO - Setting Variable

I'm having trouble trying to set a variable then use it in a select statement. I keep getting a "general error" and can't figure out what I'm doing wrong. Any input would be appreciate. I'm trying to set a variable using subqueries with named parameters.
$query = $dbh->prepare("Set #available = (SELECT SUM(payments) FROM payments WHERE customer = :customer) - (SELECT SUM(charges) FROM charges WHERE customer = :customer); SELECT #available");
$query->bindParam(":customer", $customer);
$query->execute();
If you want to use MySQL user variables, for some reason, you don't need multi-queries support. They (user variables) live as long as you session (connection) is open. Therefore you can do something like this
$customer = 1;
try {
$db = new PDO('mysql:host=localhost;dbname=dbname;charset=UTF8', 'user', 'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = "SET #available = (SELECT SUM(payments) FROM payments WHERE customer = ?) -
(SELECT SUM(charges) FROM charges WHERE customer = ?)";
$query = $db->prepare($sql);
$query->execute(array($customer, $customer));
$query = $db->prepare("SELECT #available");
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo "Exeption: " .$e->getMessage();
$result = false;
}
$query = null;
$db = null;
var_dump($result);
Sample output:
array(1) {
[0]=>
array(1) {
["#available"]=>
string(6) "100.00"
}
}
PDO doesn't seem to offer any formalised support for multi-queries (but some support does seem to be available), but mysqli does. Neither offer support for prepared multiple statements, though.
You can use mysqli like this:
$mysqli = new mysqli('servername', 'username', 'password', 'dbname');
$query = sprintf("Set #available = (SELECT SUM(payments) FROM payments WHERE customer = %1$s)" .
" - (SELECT SUM(charges) FROM charges WHERE customer = %1$s);".
" SELECT #available",
$mysqli->real_escape_string($customer) );
// Following code lifted from PHP Manual.
// This code will read multiple results, if they're available.
// Your query only returns one.
/* execute multi query */
if ($mysqli->multi_query($query)) {
do {
/* store first result set */
if ($result = $mysqli->store_result()) {
while ($row = $result->fetch_row()) {
printf("%s\n", $row[0]);
}
$result->free();
}
/* print divider */
if ($mysqli->more_results()) {
printf("-----------------\n");
}
} while ($mysqli->next_result());
}
The reference is here

can this phpbb query be optimized?

Here's some code adapted from phpBB. Near as I can tell it's trying to delete all topics wherein the only poster is the target user.
(note that for testing purposes I changed the final query from a DELETE to a SELECT)
<?php
$user_id = 66275;
mysql_connect('localhost', 'username', 'password');
mysql_select_db('db_name');
$start = microtime(true);
$total = 0;
define('POSTS_TABLE', 'phpbb_posts');
define('TOPICS_TABLE', 'phpbb_topics');
$sql = 'SELECT topic_id, COUNT(post_id) AS total_posts
FROM ' . POSTS_TABLE . "
WHERE poster_id = $user_id
GROUP BY topic_id";
$result = mysql_query($sql);
$topic_id_ary = array();
while ($row = mysql_fetch_assoc($result))
{
$topic_id_ary[$row['topic_id']] = $row['total_posts'];
}
mysql_free_result($result);
if (sizeof($topic_id_ary))
{
$sql = 'SELECT topic_id, topic_replies, topic_replies_real
FROM ' . TOPICS_TABLE . '
WHERE ' . sql_in_set('topic_id', array_keys($topic_id_ary));
$result = mysql_query($sql);
$del_topic_ary = array();
while ($row = mysql_fetch_assoc($result))
{
if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']])
{
$del_topic_ary[] = $row['topic_id'];
}
}
mysql_free_result($result);
if (sizeof($del_topic_ary))
{
$sql = 'SELECT topic_id FROM ' . TOPICS_TABLE . '
WHERE ' . sql_in_set('topic_id', $del_topic_ary);
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result))
{
$total++;
echo $row[topic_id] . "\r\n";
}
}
}
function sql_in_set($field, $array, $negate = false, $allow_empty_set = false)
{
if (!sizeof($array))
{
if (!$allow_empty_set)
{
// Print the backtrace to help identifying the location of the problematic code
$this->sql_error('No values specified for SQL IN comparison');
}
else
{
// NOT IN () actually means everything so use a tautology
if ($negate)
{
return '1=1';
}
// IN () actually means nothing so use a contradiction
else
{
return '1=0';
}
}
}
if (!is_array($array))
{
$array = array($array);
}
if (sizeof($array) == 1)
{
#reset($array);
$var = current($array);
return $field . ($negate ? ' <> ' : ' = ') . $var;
}
else
{
return $field . ($negate ? ' NOT IN ' : ' IN ') . '(' . implode(', ', $array) . ')';
}
}
$elapsed = microtime(true) - $start;
echo "\r\ntook $elapsed seconds";
echo "\r\ngot $total rows back";
?>
This does three queries. First gets all the topics the target user has posted in and the number of times they've posted in each topic. The second gets how many replies each topic in the first query actually has. Then there's some PHP code to see which topics have had all their posts made by the target user. After that the code (prior to my changes) DELETEs all those topics.
Overall it seems to me that this could be written better by doing something like this:
SELECT t.topic_id
FROM phpbb_topics AS t
JOIN phpbb_posts AS p1
ON p1.topic_id = t.topic_id
AND p1.poster_id = $poster_id
LEFT JOIN phpbb_posts AS p2
ON p2.topic_id = t.topic_id
AND p2.poster_id <> $poster_id
WHERE p2.poster_id IS NULL;
Or maybe this:
SELECT t.topic_id
FROM phpbb_topics AS t
JOIN phpbb_posts AS p1
ON p1.topic_id = t.topic_id
AND p1.poster_id = $poster_id
AND t.topic_poster = $poster_id
AND t.topic_last_poster_id = $poster_id
LEFT JOIN phpbb_posts AS p2
ON p2.topic_id = t.topic_id
AND p2.poster_id <> $poster_id
WHERE p2.poster_id IS NULL
Testing this is actually quite difficult thanks to MySQLs caching but... from what testing I have been able to do it seems like the way phpBB is currently doing it is in fact faster. Which is surprising to me.
Any ideas?
It looks to me like you are on the right track. Try adding indexes to all the columns you are using in the joins as this can often drastically increase the speed of joins.