mysqli_affected_rows, mysql subtract 2 columns error - php

I have a column I want to update with results of the difference between 2 mysql columns and count how many rows were affected. In my case it can only be 1. This is the mysql query I am using which is not consistent at all
$connection->query("UPDATE items SET Quantity_Available = Quantity - Quantity_Committed WHERE Item_ID = '$itemid'");
if($count=$connection->affected_rows!=1){echo $count;die('makassi');}
If I replace the Quantity_Committed with a numeric value, I get what I want i.e the code continues. However if I leave it as it is, I get the proper $count figure(1) but it also fails by echoing 'makassi' which it shouldn't.
Is this an improper way of subtracting 2 mysql columns or is this a bug in the php mysqli api??
This is really baffling to me!! Help please

This is a bad practice what you are trying to do. If a column in the database is derived from another column already in the column. Then such is create redundancy is the database. All a database should be normalized as much as possible. Please read here about data normalization.
Whatever you are trying to do can be achieved in a much better way. Like
Filtering the records
SELECT * FROM items WHERE Quantity - Quantity_Column > 5
Or, retrieving the quantity available.
SELECT (Quantify - Quantity_Column) as `Quality_Available` from items

Related

MySQL - How to update two tables with one query where table 2 value is true?

Okay, I am trying to update two tables without using PHP and querying a loop.
Table one: users
Table two: traits
BOTH tables have a matching row "ID" (so ID 1 in "users" is also ID 1 in "traits").
TABLE 1 has two rows that need updating: "HP" and "EXP".
TABLE 2 has one row: "STUFF".
I need a simple query to update HP and EXP ONLY if STUFF = 0.
So something like:
UPDATE users,traits
SET
traits.hp = 3,
traits.exp = 10
WHERE
traits.hp < traits.maxhp
AND users.stuff = 0;
This query seems to work, but it is very slow. Is there a better way?
Thank you!
-Josh
Depending on the table size, I would recommend creating a couple indexes on those table columns (traits.hp, traints.maxhp and users.stuff) to help keep the query quick.
Also, make sure that your traits.hp and traits.maxhp are set as some sort of numerical (eg. INT) type, otherwise the server will need to try and convert it on-the-fly, which could slow things down as well.

Optimal mySQL table index structure for faster SELECT of a large range of daily data

I am wondering the best format to lay out my data in a mySQL table so that it can be queried in the fastest manner to gather an array of daily values to be further utilized by php.
So far, I have laid out the table as such:
item_id price_date price_amount
1 2000-03-01 22.4
2 2000-03-01 19.23
3 2000-03-01 13.4
4 2000-03-01 14.95
1 2000-03-02 22.5
2 2000-03-02 19.42
3 2000-03-02 13.4
4 2000-03-02 13.95
with item_id defined as an index.
Also, I am using:
"SELECT DISTINCT price_date FROM table_name"
to get an array containing a unique list of dates.
Furthermore, the part of the code that is within a loop (and the focus of my optimization question) is currently written as:
"SELECT price_amount FROM table_name WHERE item_id = 1 ORDER BY price_date"
This second "SELECT" statement is actually within a loop where I am selecting/storing-in-array the daily prices of each item_id requested.
All is currently functioning and pulling the data from mySQL properly, however, both the above listed "SELECT" statements are taking approx 4-5 seconds to complete per each run, and when looping through 100+ products to create a summary, adds up to a very inefficient/slow information system.
Is there any more-efficient way that I could structure the mySQL table and/or SELECT statements to retrieve the results faster? Perhaps defining a different index on a different column? I have used the EXPLAIN command to return information per the queries but am unsure how to use the EXPLAIN information to increase the efficiency of my queries.
Thanks in advance for any mySQL wizards that may be able to assist.
Single column index
I am using:
"SELECT DISTINCT price_date FROM table_name"
to get an array containing a unique list of dates.
This query can be executed more efficiently if you create an index for the price_date column:
ALTER TABLE table_name ADD INDEX price_idx (price_date);
Mutiple column index
Furthermore, the part of the code that is within a loop (and the focus of my optimization question) is currently written as:
"SELECT price_amount FROM table_name WHERE item_id = 1 ORDER BY price_date"
For the second query, you should create an index covering both the item_id and price_date column:
ALTER TABLE table_name ADD INDEX item_price_idx (item_id, price_date);
I know this is a bit late, but i stumbled across this and thought I would throw my thoughts into the mix.
Indexes used well are very helpful in speeding up queries (Explain shows some really godd results around which indexes are being chosen - if any - for a specific query). However efficient PHP will help even more.
In your case you do not show the PHP, but it looks like you offer a list of dates and then loop through finding all the items in that date to get the prices. It would be more efficient to do something like the following:
Select item_id, price_amount from table_name where price_date= order by item_id, price_amount
with an index (preferably a Unique Index) on price_date,item_id,price_amount
You then have a single loop through the resultant SQL not a loop with multiple SQL connections (this is especially true if your SQL server is separate from the PHP box as an external network connection can have an overhead).
4-5 seconds for a single query though is very slow )by a factor of at least 100x) so it would indicate a problem (very large table with no key to use) or disk issues (potentially).

MYSQL Best Row Count Method - Large Database

I have a MySQL database that contains over 400,000 rows. For my web based script, I have a page function. One of the steps to determine how many pages there should be is returning the number of rows in the table.
Let's pretend the table name is data.
I'm wondering what is the most efficient method to ONLY return the number of rows in the database.
I could obviously do something like:
$getRows = mysql_query("SELECT id FROM `data`") or die(mysql_error());
$rows = mysql_num_rows($getRows);
So that it only selects the id. But still, that will be selecting 400,000 + ID's worth of data and storing it on the stack (i think?) and seems less efficient as using a method such as finding the table status. I'm just not 100% sure how to use the table status method.
Feedback & opinions would be awesome. Thanks guys!
use count
SELECT count(id) FROM data
See this question for more info on getting counts. Make sure your id has an index in your table.
Now, to find the number of unique rows, you can do
SELECT count(distinct(id)) FROM data
alternatively, if you want to find the highest ID number (if you ID are autoincremental and unique) you can try SELECT max(id) FROM data to return the highest ID number present.
I'd highly recommend this site to learn these basic functions:
http://sqlzoo.net/
400,000 rows is not a lot at all. Keep it simple and just do:
select count(*)
from `data`

Optimizing an MYSQL COUNT ORDER BY query

I have recently written a survey application that has done it's job and all the data is gathered. Now i have to analyze the data and i'm having some time issues.
I have to find out how many people selected what option and display it all.
I'm using this query, which does do it's job:
SELECT COUNT(*)
FROM survey
WHERE users = ? AND table = ? AND col = ? AND row = ? AND selected = ?
GROUP BY users,table,col,row,selected
As evident by the "?" i'm using MySQLi (in php) to fetch the data when needed, but i fear this is causing it to be so slow.
The table consists of all the elements above (+ an unique ID) and all of them are integers.
To explain some of the fields:
Each survey was divided into 3 or 4 tables (sized from 2x3 to 5x5) with a 1 to 10 happiness grade to select form. (questions are on the right and top of the table, then you answer where the questions intersect)
users - age groups
table, row, col - explained above
selected - dooooh explained above
Now with the surveys complete and around 1 million entries in the table the query is getting very slow. Sometimes it takes like 3 minutes, sometimes (i guess) the time limit expires and you get no data at all. I also don't have access to the full database, just my empty "testing" one since the costumer is kinda paranoid :S (and his server seems to be a bit slow)
Now (after the initial essay) my questions are: I left indexing out intentionally because with a lot of data being written during the survey, it would be a bad idea. But since no new data is coming in at this point, would it make sense to index all the fields of a table? How much sense does it make to index integers that never go above 10? (as you can guess i haven't got a clue about indexes). Do i need the primary unique ID in this table? I
I read somewhere that indexing may help groups but only if you group by the first columns in a table (and since my ID is first and from my point of view useless can i remove it and gain anything by it?)
Is there another way to write my query that would basically do the same thing but in a shorter period of time?
Thanks for all your suggestions in advance!
Add an index on entries that you "GROUP BY" or do "WHERE". So that's ONE index incorporating users,table,col,row and selected in your case.
Some quick rules:
combine fields to have the WHERE first, and the GROUP BY elements last.
If you have other queries that only use part of it (e.g. users,table,col and selected) then leave the missing value (row, in this example) last.
Don't use too many indexes/indeces, as each will slow the table to updates marginally - so on really large system you need to balance queries with indexes.
Edit: do you need the GROUP BY user,col,row as these are used in the WHERE. If the WHERE has already filtered them out, you only need group by "selected".

How to get affected rows in previous MySQL operation?

mysql_affected_rows is to get number of affected rows in previous MySQL operation, but I want to get affected rows in previous MySQL operation.
For example:
update mytable set status=2 where column3="a_variable";
Before this operation, status of some rows is already 2, and I want to get affected rows in previous MySQL operation, you can not get it by issuing a query of
select * from mytable where status=2
So how to do this work?
It can be efficiently and simply achieved with the following:
select * from mytable where column3="a_variable" and status != 2;
update mytable set status=2 where column3="a_variable";
The result of the first query are the rows that are going to change, and the second query actually changes them.
If this is a high performance system, you may need to take special care with transactions to prevent a new row slipping in between those 2 queries.
The implementation and function you are asking about is from PHP, please tag your question with PHP.
In response to your question tho, in order to do what you are suggesting you would need to keep a copy of the SQL table prior to the change and compare it with the table after the change, the resulting difference would be your answer. You can do this in PHP by simply loading the table contents into an array and comparing the arrays before and after, any new/changed data is your answer (Please note: it is highly not recommended you do this as it can cause an increased load on your server depending on the amount of data stored in the tables.)

Categories