Can someone explain how SQLite3 is used to give the number of rows found in a query?
mysql has mysql_num_rows and SQLite2 has a similar function but someone in SQLite3 development seems to have forgotten to add that function.
The examples that I have seen here and on other sites do not answer the question but instead only create more questions.
SO...
I have a query like $queryStr = $d->query("SELECT * FROM visitors WHERE uid='{$userid}' AND account='active';");
what I want to know is how do I find out how many results are in $queryStr
I am not looking for the number of rows in the database, just the number of rows in the "query results"
SQLite computes query results on the fly (because this is more efficient for an embedded database where there is no network communication).
Therefore, it is not possible to find out how many records a query returns without actually stepping through all those records.
You should, if at all possible, structure your algorithm so that you do not need to know the number of records before you have read them.
Otherwise, you have to execute a separate query that uses SELECT COUNT(*) to return the number of records, like this:
$countQuery = $d->query("SELECT COUNT(*) FROM visitors WHERE uid='{$userid}' AND account='active';");
Related
I am using the ActiveRecord library that comes with the PHP framework CodeIgniter. I frequently find myself needing to query the database for a number of rows using a LIMIT clause, but also needing to know the total number of rows I would have pulled had I not included the LIMIT clause. For example, this is frequently the case when I provide pagenation for many results. I only want to pull 20 records at a time, but I also need to know how many rows there are in total which match my query where clause. I need to create 2 slightly different queries, a count query:
SELECT * FROM table WHERE [where_clause];
And a 'paged' query:
SELECT * FROM table WHERE [where_clause] LIMIT 0,20;
Is there an elegant solution to this problem with ActiveRecord? There doesn't seem to be anything out of the box which will help me. Obviously I can write around the problem with my own PHP but it would be ideal if I could take advantage of some aspect of the library to not have to duplicate code, etc.
Answer my own question, best way is to use SQL_CALC_FOUND_ROWS like so, Add this select call to your query:
$this->db->select('SQL_CALC_FOUND_ROWS *',false);
And then immediately afterwards to get the count:
$count = $this->db->query("SELECT FOUND_ROWS() AS count")->row('count');
In my program I launch an SQL query and get back a result resource. I then iterate through the rows of this result resource using the mysql_fetch_array() function and use the contents of the fields of each row to construct a further SQL query.
The result of launching this second query is the first set of results that I want. However, because the number of results produced by doing this is not many I want to make the search less specific by dropping the last record used to make the query.
e.g. the query which produces the first set of results I want could be:
SELECT uid FROM users WHERE (gender=male AND relationship_status=single
AND shoe_size=10)
I would then want to drop the last record so that my query became:
SELECT uid FROM users WHERE (gender=male AND relationship_status=single)
I have already written code to produce the first query but as I mentioned above I use the mysql_fetch_array function to iterate through ALL of the records. In subsequent "rounds" I only want to iterate through successively less records so that my query is less specific. How can I do this?
This seems like an very inefficient method too - so I'm welcome to any simple ideas which might make it more efficient.
EDIT: Thanks for the reply - Yeah I am actually doing this in my program. I am basically trying to implement a basic search algorithm by taking all the preferences a user has specified in the DB and using it to form a query to look for people with those preferences. So the first time search using all the criteria, then on successive attempts search using one less criteria and negate the user ids which were previously returned. At the moment I am constructing the query from scratch for each "round", but I want to find a way I can do this using the last query
Using the queries above, you could do:
SELECT uid
FROM users
WHERE uid NOT IN (
SELECT uid
FROM users
WHERE
(gender=male
AND relationship_status=single
AND shoe_size=10)
)
This will essentially turn your first query into a sub-query, and use that to negate the results returned. Ie, it will return all the rows, NOT IN the first query.
I have a MySQL Database table with peoples names with thousands of rows.
I'm coding a search script for this table to display the most similiar names stored in the table.
So I thought of fetching ALL the rows of the table, then using a FOREACH loop that will call similar_text() (a function that returns a percentage number) and then display on the table only the names that matches 60% of similarity.
Will my website performance slow too much if do this (fetching all rows)?
Will my server bandwidth suffer because of that?
ps: 'SOUNDS LIKE' MySQL command doesn't help much on this case
Let the database do the searching.
See this question, looks like what you need: How to find similar results and sort by similarity?
Yes this will most likely slow down your site, especially as your site grows and you have many users searching simultaneously.
If possible use a stored procedure or user defined function inside the database to do the searching. Also even if you don't know the exact spelling of the entry you are looking for, if you know the first letter you can speed up the search. You can use something like WHERE name LIKE 'F%' AND similar_text(name, 'FOOBAR') > 0.6 because then an index can be used to find only those rows that start with F.
Can some shed some light on hoe to get the number of rows (using php) in a table without actually having to read all the rows? I am using squlite to log data periodically and need to know the table row count before I actually access specific data?
Apart from reading all rows and incrementing a counter, I cannot seem to work out how to do this quickly (it's a large database) rather simple requirement? I have tried the following php code but it only returns a boolean response rather that the actual number of rows?
$result = $db->query('SELECT count(*) FROM mdata');
Normally the SELECT statement will also return the data object (if there is any?)
Just use
LIMIT 1
That should work!! It Limits the result to ONLY look at 1 row!!
if you have record set then you get number or record by mysql_num_rows(#Record Set#);
I have used MySQL a lot, but I always wondered exactly how does it work - when I get a positive result, where is the data stored exactly? For example, I write like this:
$sql = "SELECT * FROM TABLE";
$result = mysql_query($sql);
while ($row = mysql_fetch_object($result)) {
echo $row->column_name;
}
When a result is returned, I am assuming it's holding all the data results or does it return in a fragment and only returns where it is asked for, like $row->column_name?
Or does it really return every single row of data even if you only wanted one column in $result?
Also, if I paginate using LIMIT, does it hold THAT original (old) result even if the database is updated?
The details are implementation dependent but generally speaking, results are buffered. Executing a query against a database will return some result set. If it's sufficiently small all the results may be returned with the initial call or some might be and more results are returned as you iterate over the result object.
Think of the sequence this way:
You open a connection to the database;
There is possibly a second call to select a database or it might be done as part of (1);
That authentication and connection step is (at least) one round trip to the server (ignoring persistent connections);
You execute a query on the client;
That query is sent to the server;
The server has to determine how to execute the query;
If the server has previously executed the query the execution plan may still be in the query cache. If not a new plan must be created;
The server executes the query as given and returns a result to the client;
That result will contain some buffer of rows that is implementation dependent. It might be 100 rows or more or less. All columns are returned for each row;
As you fetch more rows eventually the client will ask the server for more rows. This may be when the client runs out or it may be done preemptively. Again this is implementation dependent.
The idea of all this is to minimize roundtrips to the server without sending back too much unnecessary data, which is why if you ask for a million rows you won't get them all back at once.
LIMIT clauses--or any clause in fact--will modify the result set.
Lastly, (7) is important because SELECT * FROM table WHERE a = 'foo' and SELECT * FROM table WHERE a = 'bar' are two different queries as far as the database optimizer is concerned so an execution plan must be determined for each separately. But a parameterized query (SELECT * FROM table WHERE a = :param) with different parameters is one query and only needs to be planned once (at least until it falls out of the query cache).
I think you are confusing the two types of variables you're dealing with, and neither answer really clarifies that so far.
$result is a MySQL result object. It does not "contain any rows." When you say $result = mysql_query($sql), MySQL executes the query, and knows what rows will match, but the data has not been transferred over to the PHP side. $result can be thought of as a pointer to a query that you asked MySQL to execute.
When you say $row = mysql_fetch_object($result), that's when PHP's MySQL interface retrieves a row for you. Only that row is put into $row (as a plain old PHP object, but you can use a different fetch function to ask for an associative array, or specific column(s) from each row.)
Rows may be buffered with the expectation that you will be retrieving all of the rows in a tight loop (which is usually the case), but in general, rows are retrieved when you ask for them with one of the mysql_fetch_* functions.
If you only want one column from the database, then you should SELECT that_column FROM .... Using a LIMIT clause is also a good idea whenever possible, because MySQL can usually perform significant optimizations if it knows that you only want a certain group of rows.
The first question can be answered by reading up on resources
Since you are SELECTing "*", every column is returned for each mysql_fetch_object call. Just look at print_r($row) to see.
In simple words the resource returned it like an ID that the MySQL library associate with other data. I think it is like the identification card in your wallet, it's just a number and some information but asociated with a lot of more information if you give it to the goverment, or your cell-phone company, etc.