I have a mysql query that retrieves all my topic results. I then have a pagination system where results are separated into pages and the query's limit #,# changes based on what page you are on.
What I want to do is put all those results into two separate div containers. I want 21 results on each page. The first 9 I will put in one div. The next 12 will go in the other. Does anyone know an efficient way to do this? Should I use two queries, or javascript, or another way? I am just looking for the best most efficient way to do this. Unfortunately the pagination system makes two queries difficult. Any suggestions highly appreciated.
$sql = "SELECT * FROM topics LIMIT ?,?";
$stmt2 = $conn->prepare($sql);
$result=$stmt2->execute(array(somenumber,somenumber2));
I don't see any reason why you can't do a single MySQL query and use JavaScript to sort the results. Understand that I don't understand here what your data is coming back looking like, so any example I provide will have to remain pretty agnostic in this regard.
I will, however, assert as an assumption that you have a JavaScript array of length 21 with some data that is the basis for your display.
Assuming that we're just talking about the first 9, and the last 12, the sorting code is as simple as:
// assume my_array is the array mentioned above
for (var i = 0; i < 9; i += 1) {
var html = code_to_transform_data_from_array(array[i]);
$('.div1').append($(html));
}
for (var i = 9; i < 21; i += 1) {
var html = code_to_transform_data_from_array_b(array[i]);
$('.div2').append($(html));
}
If your sorting condition is any more complicated, then you'd be better off with something like...
while (my_array.length > 0) {
var item = my_array.pop();
if (sorting_condition) {
$('.div1').append(f1(item));
}
else {
$('.div2').append(f2(item));
}
}
(In the second example, I became a lazy typist and assumed f1 and f2 to be complete transformation functions. sorting_condition is your criteria for determining in which bucket something goes.
Hope that sets you off on the right track.
Related
I'm writing a filter/sorting feature for an application right now that will have text fields above each column. As the user types in each field, requests will be sent to the back-end for sorting. Since there are going to be around 6 text fields, I was wondering if there's a better way to sort instead of using if statements to check for each variable, and writing specific queries if say all fields were entered, just one, or just two fields, etc.
Seems like there would be a lot of if statements. Is there a more intuitive way of accomplishing this?
Thanks!
Any initial data manipulation, such as sorting, is usually done by the database engine.
Put an ORDER BY clause in there, unless you have a specific reason the sorting needs done in the application itself.
Edit: You now say that you want to filter the data instead. I would still do this at the database level. There is no sense in sending a huge dataset to PHP, just for PHP to have to wade through it and filter out data there. In most cases, doing this within MySQL will be far more efficient than what you can build in PHP.
Since there are going to be around 6 text fields, I was wondering if there's a better way to sort instead of using if statements to check for each variable
Definitely NO.
First, nothing wrong in using several if's in order.
Trust me - I myself being a huge fan of reducing repetitions of code, but consider these manually written blocks being the best solution.
Next, although there can be a way to wrap these condition ns some loop, most of time different conditions require different treatment.
however, in your next statements you are wrong:
and writing specific queries
you need only one query
Seems like there would be a lot of if statements.
why? no more than number of fields you have.
here goes a complete example of custom search query building code:
$w = array();
$where = '';
if (!empty($_GET['rooms'])) $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";
the only fields filled by the user going to the query.
the ordering is going to be pretty the same way.
mesc is an abbreviation for the mysql_real_escape_string or any other applicable database-specific string escaping function
select * from Users
order by Creadted desc, Name asc, LastName desc, Status asc
And your records will be sorted by order from query.
First by Created desc, then by Name asc and so on.
But from your question I can see that you are searching for filtering results.
So to filter by multiple fileds just append your where, or if you are using any ORM you can do it through object methods.
But if its simple you can do it this way
$query = "";
foreach($_POST['grid_fields'] as $key => $value)
{
if(strlen($query) > 0)
$query .= ' and '
$query .= sprintf(" %s LIKE '%s' ", mysql_real_escape_string($key), '%' .mysql_real_escape_string($value) .'%');
}
if(strlen($query) > 0)
$original_query .= ' where ' . $query;
this could help you to achieve your result.
No. You cannot avoid the testing operations when sorting the set, as you have to compare the elements in the set in same way. The vehicle for this is an if statement.
Could you take a look at this?
WHERE (ifnull(#filter1, 1) = 1 or columnFilter1 = #filter1)
and (ifnull(#filter2, 1) = 1 or columnFilter2 = #filter2)
and (ifnull(#filter3, 1) = 1 or columnFilter3 = #filter3)
and (ifnull(#filter4, 1) = 1 or columnFilter4 = #filter4)
and (ifnull(#filter5, 1) = 1 or columnFilter5 = #filter5)
and (ifnull(#filter6, 1) = 1 or columnFilter6 = #filter6)
Please let me know if I'm misunderstanding your question.. It's not like an IF statement batch, and is pretty lengthy, but what do you think?
I have a table in database that has 2 columns Name | Age, I display it in a HTML page.
I want to sort the table in HTML page based on a field when the user clicks on it.
I have a PHP function to do the sorting based on a field.
But after obtaining the rows in sorted order in PHP, I'm looking for ways by which I can update the HTML table without navigating away from the page.
You do not need to communicate between the client and server to do this, just sort the table on the client directly.
There is a jQuery plug-in for this that works quite well:
http://tablesorter.com/docs/
You can do sorting in javascript, without having to communicate with the server. For example, this code will sort a table based on the content of the Nth column:
function sortTable(table, column, skipHeader) {
// Stick each row into an array.
var rows = [];
for (var i = skipHeader ? 1 : 0; i < table.rows.length; i++) {
rows.push(table.rows[i]);
}
// Sort the array based on the innerText of the column'th cell in each row
rows.sort(function(a, b){
a = a.cells[column].innerText;
b = b.cells[column].innerText;
return a < b ? -1 : (b < a ? 1 : 0);
});
// Re-order the rows by removing/appending in the sort order
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var container = row.parentElement;
container.removeChild(row);
container.appendChild(row);
}
}
For example, to sort the first table in the document, on the first column, and skip the header row:
sortTable(document.getElementsByTagName('table')[0], 0, true);
Obviously you'll want to modify this to suit your own tastes, especially the sorting, but it's a lot simpler than having to post the data back to the server, which I think is what you're proposing.
Since others have covered the fact that client-side sorting would work just fine here, I'll just point you to the resource with which I've had the most sucess doing this kind of thing: Google Data Tables, part of their Visualization Library. Here are the deets on what you can do (spoiler: everything you want and more).
Here is a link to a javascript library to make your tables sortable using javascript instead of php. I've used it many times, it works great.
Javascript Sortable Tables by: Stuart Langridge
I am seeking some advice on the best way to retrieve and display my data using MySQL and PHP.
I have 3 tables, all 1 to many relationships as follows:
Each SCHEDULE has many OVERRIDES and each override has many LOCATIONS. I would like to retrieve this data so that it can all be displayed on a single PHP page e.g. list out my SCHEDULES. Within each schedule list the OVERRIDES, and within each override list the LOCATIONS.
Option1 - Is the best way to do this make 3 separate SQL queries and then write these to a PHP object? I could then iterate through each array and check for a match on the parent array.
Option 2 - I have thought quite a bit about joins however doing two right joins will return me a row for every entrance in all 3 tables.
Any thoughts and comments would be appreciated.
Best regards, Ben.
If you really want every piece of data, you're going to be retrieving the same number of rows, no matter how you do it. Best to get it all in one query.
SELECT schedule.id, overrides.id, locations.id, locations.name
FROM schedule
JOIN overrides ON overrides.schedule_id = schedule.id
JOIN locations ON locations.override_id = overrides.id
ORDER BY schedule.id, overrides.id, locations.id
By ordering the results like this, you can iterate through the result set and move on to the next schedule whenever the scheduleid changes, and the next location when the locationid changes.
Edit: a possible example of how to turn this data into a 3-dimensional array -
$last_schedule = 0;
$last_override = 0;
$schedules = array();
while ($row = mysql_fetch_array($query_result))
{
$schedule_id = $row[0];
$override_id = $row[1];
$location_id = $row[2];
$location_name = $row[3];
if ($schedule_id != $last_schedule)
{
$schedules[$schedule_id] = array();
}
if ($override_id != $last_override)
{
$schedules[$schedule_id][$override_id] = array();
}
$schedules[$schedule_id][$override_id][$location_id] = $location_name;
$last_schedule = $schedule_id;
$last_override = $override_id;
}
Quite primitive, I imagine your code will look different, but hopefully it makes some sense.
I'm using an if clause to fetch the value of my mysql table data because my table schema is not normal.
now for getting these values, I wrote the below code:
$result = $db->sql_query("SELECT type, var, count from table_counter");
while ($row = $db->sql_fetchrow($result)) {
$type = $row['type'];
$var = $row['var'];
$count = intval($row['count']);
if(($type == "total") && ($var == "visits")) {
$totalVisits= $count;
}elseif(($type == "total") && ($var == "pageviews")) {
$totalPVisits= $count;
}
}
Is there any other way rather than using an if clause?!
SELECT `type`, `var`, SUM(`count`) AS `sum`
FROM table_counter
GROUP BY `type`,`var`;
There's no need for that intval() to convert the count field to integer. It's already defined as an integer in your MySQL table.
What you have here is some kind of EAV data structure and the if is a common way to fetch from it. There are other ways of pivoting them.
What are you aiming to do with the data? Just create the counts?
You could extract the data in more than one query.
Another option is to put the data into an array, then sort it using PHP array sort functions. It could then be split it into two separate arrays, if needed.
You will need to pivot the data. And that will require you to write some code to parse out what you need in php and mysql. This will can get heavy depending on how much data you want and how it's stored and how it needs to be retrieved. Based on your question text it looks you are storing very simple data, but for every type and set of data you are storing you will need to create logic for it.
Soooo, if you know exactly what the variables are going to be you could set up and array of the variable names you want set and loop through them.
$legal_values = array('visits', 'pageviews', etc...);
while ($row = $db->sql_fetchrow($result)) {
if (in_array($row['var'], $legal_values)) {
$$row['var'] = $intval($row['count'];
}
}
This is just a simple example and only works if all the types are count. Obviously if you want to filter it down you will need more logic. There isn't really a catch-all solution for this stuff, so it comes down to writing something that is simple so you understand it and you can easily extend it to handle more data that you might need later.
${$row['type'] . ucfirst($row['var'])} = $row['count'];
That reads total pageviews 107 to $totalPageviews = 107. Depending on where you want to use this, this may be a possibility.
I have two msyql tables, Badges and Events. I use a join to find all the events and return the badge info for that event (title & description) using the following code:
SELECT COUNT(Badges.badge_ID) AS
badge_count,title,Badges.description
FROM Badges JOIN Events ON
Badges.badge_id=Events.badge_id GROUP
BY title ASC
In addition to the counts, I need to know the value of the event with the most entries. I thought I'd do this in php with the max() function, but I had trouble getting that to work correctly. So, I decided I could get the same result by modifying the above query by using "ORDER BY badgecount DESC LIMIT 1," which returns an array of a single element, whose value is the highest count total of all the events.
While this solution works well for me, I'm curious if it is taking more resources to make 2 calls to the server (b/c I'm now using two queries) instead of working it out in php. If I did do it in php, how could I get the max value of a particular item in an associative array (it would be nice to be able to return the key and the value, if possible)?
EDIT:
OK, it's amazing what a few hours of rest will do for the mind. I opened up my code this morning, and made a simple modification to the code, which worked out for me. I simply created a variable on the count field and, if the new one was greater than the old one, changed it to the new value (see the "if" statement in the following code):
if ( $c > $highestCount ) {
$highestCount = $c; }
This might again lead to a "religious war", but I would go with the two queries version. To me it is cleaner to have data handling in the database as much as possible. In the long run, query caching, etc.. would even out the overhead caused by the extra query.
Anyway, to get the max in PHP, you simply need to iterate over your $results array:
getMax($results) {
if (count($results) == 0) {
return NULL;
}
$max = reset($results);
for($results as $elem) {
if ($max < $elem) { // need to do specific comparison here
$max = $elem;
}
}
return $max;
}