How to update mysql database fields in groups (using GROUP BY) - php

I have a table named youi in my database. All fields in the table already contain values except for the aff and desc fields. See image below.
Now, I have a form in my HTML page (See image below) where I want to update the desc and aff fields according to their camp. I have not yet dealt with this kind of setup before. I've been thinking how to do this for almost a day now but still can't seem to find a perfect solution. Could you give me ideas or solutions on how to achieve this? I'm using PHP and mySQL.
Thanks in advance!

The easiest way i see is using a different UPDATE for each of those lines.
You could do that in a loop in php where you construct your update with the values of aff, desc and campaign for each line.
The sql would be:
UPDATE tableName
SET aff = varAffiliate,
desc = varDescription
WHERE campaign = varCampaign;
The php part i'm not of much help, sorry.

You can use CASE, WHEN and THEN in a loop to make the one query.
This is a statement I created using a simple for loop to update a bunch of captions on a group of photos.
UPDATE Images SET caption = CASE imgID WHEN 389 THEN 'a' WHEN 390 THEN 'sdf' WHEN 391 THEN 'safasasadf' WHEN 392 THEN 'fs' WHEN 393 THEN 'dfdsf' WHEN 394 THEN 'sfdf' END WHERE imgID IN (389,390,391,392,393,394);
Hope that helps
aff = (case when somefield='slkd' then yyy end),
desc = (case when somefield='slkdfdsd' then xxx end)

I finally found a solution to this problem. I used combination of jQuery, AJAX, PHP and mySQL for it to work.
All <select> have the same id. The same for <input> and <label>. Here's a sample of my HTML code:
<select id="youiaff">
<option>1001</option>
<option>1007</option>
<option>1009</option>
<option>1013</option>
<option>1017</option>
<option>1018</option>
<option>1022</option>
</select>
<input id="youidesc" type="text" />
<label id="youicamp"></label>
<button type='button' class='btn btn-success saveyouiid'>Save</button>
What I did next was to create a jQuery code that will get all the values of <select>, <input> & <label> and put each of them in an array. I used their ids as identifiers. Here's the code:
var desc = $("input[id='youidesc']")
.map(function(){return $(this).val();}).get();
var aff = $("select[id='youiaff']")
.map(function(){return $(this).val();}).get();
var camp = $("label[id='youicamp']")
.map(function(){return $(this).text();}).get();
Then, I passed the variables to the PHP script using AJAX:
$.ajax({
type: 'post',
url: 'saveyouiid.php',
data: {
desc:desc,
aff:aff,
camp:camp,
},
success:function(data){
}
});
This codes will be executed upon clicking the save button. So the full jQuery/AJAX for this would be:
$('.saveyouiid').click(function(){
var desc = $("input[id='youidesc']")
.map(function(){return $(this).val();}).get();
var aff = $("select[id='youiaff']")
.map(function(){return $(this).val();}).get();
var camp = $("label[id='youicamp']")
.map(function(){return $(this).text();}).get();
$.ajax({
type: 'post',
url: 'saveyouiid.php',
data: {
desc:desc,
aff:aff,
camp:camp,
},
success:function(data){
}
});
});
The PHP script (saveyouiid.php) will then accept the values sent via AJAX. These values are arrays. What I did next was I combined the arrays to form a multidimensional array. Then, I get the individual values and perform the mySQL query. Here's what the script looks like:
<?php
$con = mysqli_connect("localhost","imu_fryu","frankyouiIMU2013","imu_frankyoui");
if (mysqli_connect_errno($con)) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$aff = $_POST['aff'];
$desc = $_POST['desc'];
$camp = $_POST['camp'];
$arr = array_map(null, $aff, $desc, $camp);
foreach($arr as $array)
{
$aff = $array[0];
if ($aff == ">> Select Affiliate ID <<"){
$affID = "0";
}else{
$affID = $aff;
}
$desc = $array[1];
$camp = $array[2];
$sql1 = "UPDATE youi SET aff = '$affID', descr = '$desc' WHERE camp = '$camp'";
if (!mysqli_query($con,$sql1)) {
die('Error: ' . mysqli_error($con));
}
}
mysqli_close($con);
?>
I hope this could help someone in the future. :)

Related

How to return latest Mysql entry through JQuery/Ajax request

I am trying to pull the latest entry of a mysql table through ajax and display it as html content inside a div. I have ajax and php functioning correctly, the only problem I have is that I want to query for new entries and stack the results at a time interval within a loop and I've run into two problems: getting the data to behave like a normal javascript string, and getting the loop to only return unique entries.
update.php file
$con=mysqli_connect("mydbhost.com","username","password","database_name");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM conversations");
$j = 0;
while($row = mysqli_fetch_array($result))
{
$carray[j] = $row['comment'];
$j++;
}
$comment = (array_pop($carray));
echo $comment;
echo "<br>";
mysqli_close($con);
JQuery Ajax request loop:
$(document).ready(function(e){
var comment;
function commentLoop() {
comment = $('#testdiv').load('update.php');
$('#testdiv').append(comment);
setTimeout(commentLoop, 6000);
}
commentLoop();
$(document).focus();
});
The problem is by doing SELECT * FROM conversations you keep requesting whole table -- although you only take the last one.
Your code need to remember which comment has been loaded, and only get any comment newer than that.
For example, assuming your primary key is incremental, do SELECT * FROM conversations WHERE convid > ?. Replace ? with latest comment that has been loaded. If you're loading for the first time, just do SELECT * FROM conversations
You could pass the last comment id displayed using request parameter into update.php. Also I recomment returning the data in JSON format so you can return a collection of comment and id and parse it easily
This will count the comments in the table and select the last entered comment then pass them to ajax as json data only if the received count is lower than the count of the comments in the table:
PHP:
if(isset($_GET['data']))
{
$con = new mysqli('host', 'user', 'password', 'database');
$init_count = $_GET['data'];
$stmt1 = "SELECT COUNT(*) AS count FROM conversations";
$stmt2 = "SELECT comment FROM conversations ORDER BY date_column DESC LIMIT 1";
$total = $con->prepare($stmt1);
$total->execute();
$total->bind_result($count);
$total->fetch();
$total->close();
if( ($init_count != '') && ($init_count < $count) )
{
$lastComment = $con->prepare($stmt2);
$lastComment->execute();
$result = $lastComment->get_result();
$row = $result->fetch_assoc();
$lastComment->close();
$data = array(
'comment' => $row['comment'],
'count' => $count
);
}
elseif($init_count == '')
{
$data = array(
'comment' => '',
'count' => $count
);
}
$pdo->close();
echo json_encode($data);
}
HTML:
<input type="hidden" id="count" value="" />
JQUERY:
$(document).ready(function(e){
function getComment(){
var count = $('#test').val();
$.ajax({
type: 'get',
url: 'update.php?data=' + count,
dataType: 'json',
success: function(data)
{
$('#count').val(data.count);
if(data.comment) != $('#testdiv').html(data.comment);
}
});
}
getComment();
setInterval(getComment, 6000);
});
SELECT * FROM conversations order by insert_date desc limit 10
insert_date the date time comment is inserted, i hope you will have a field for storing that if not add it now

Load content from MySQL on scroll with AJAX post

I have a segment of my website which needs to dynamically load content when the user reaches the bottom. I'm using jQuery, and this is the code to detect the scroll:
$(document).ready(function() {
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("Bottom reached");
$('div#loadMoreComments').show();
dataStr = "from=" + $(".n:last").attr('id')
$.ajax({
type: "POST",
url: "ajax/query.php",
data: dataStr,
success: function(html) {
if(html){
$("#hold").append(html);
alert("Data was added");
}
else{
$('div#loadMoreComments').replaceWith("<center><h1 style='color:red'>End of countries !!!!!!!</h1></center>");
alert("Data was not added");
}
}
});
}
});
});
The first problem I have is that the scroll to the bottom is only detected when the user reaches the top of the page. The second problem is that it doesn't load any content, at all, because the variable doesn't seem to be posted, here's my code in the query.php:
if(array_key_exists('from', $_POST)) {
$from = htmlspecialchars(stripslashes(mysql_real_escape_string($_POST['from'])));
$to = 15;
$re = ("SELECT status as status, sid as sid, UNIX_TIMESTAMP(timestamp) as timestamp FROM mingle_status WHERE uid = '$uid' ORDER BY timestamp DESC LIMIT $from,$to"); //query
}
else {
$re = ("SELECT id as id, status as status, sid as sid, UNIX_TIMESTAMP(timestamp) as timestamp FROM mingle_status WHERE uid = '$uid' ORDER BY timestamp DESC LIMIT 1"); //query
}
$result = mysql_query($re) or die (mysql_error());
while($st = mysql_fetch_assoc($result)) {
$status = nl2br($st['status']);
$sid = $st['sid'];
$td = $st['timestamp'];
$id = $st['id'];
?>
<div id="<?php echo $id; ?>" class="id">
<!-- stuff -->
</div>
<?php
}
?>
And the error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '",15' at line 1
If anyone could help me with this, it'd be great, I'd really appreciate it.
EDIT: Okay, I can now get a div generated, but only when I scroll to the top of the page, and it only appends one div, and if I scroll to the top again, it appends the exact same div.
This is just wrong:
$from = htmlspecialchars(stripslashes(mysql_real_escape_string($_POST['from'])));
If from is supposed to be an integer, just use:
$from = (int) $_POST['from'];
I also see that that number comes from an id in the html and ids cannot start with a number.
Edit: An additional problem is that you are not selecting the ID in your sql query if from exists and even if you would do that, this approach can lead to problems in the future when you delete records and your IDs are not sequential any more.
About the first problem, I can solve that in firebug changing:
if($(window).scrollTop() + $(window).height() == $(document).height()) {
to:
if( ($(window).scrollTop() + $(window).height()) > ($(document).height() - 10) ) {
Edit 2: To solve your non-sequential ID problem, the easiest way would be to calculate from in javascript using something like:
dataStr = "from=" + $(".n").length; // just count the number of elements you are showing already

Searching through thousands of records (properties) and returning the data

So I have implemented a google maps, using javascript to plot a polygon. I use getBounds to get the latLongs. Then I call a database (postcodes), which contains each lat long for each postcode in the UK.
This query looks like:
SELECT * FROM `postcode`.`postcodeGoogle` WHERE (`lat` BETWEEN '$lat1' AND '$lat2')
AND (`long` BETWEEN '$long1' AND '$long2')
Which is fine, returns the right data.
I then have a second database, address_list, which contains every address in the UK (at the moment it only contains Kettering area, so 12,000 rows). I do a while loop on the first query and then on each loop run this query:
SELECT * FROM `digital_hub`.`address_list` WHERE `postcode`='".$row['postcode']."'
Then I add the latlong of the postcode to a variable:
$resultE = $resultE."(".$row['lat'].", ".$row['long'].") || ";
This then gets echoed out at the end of the loops.
This page is called via jQuery:
$.get("php/properties.php?bounds="+bounds, function(data){
var theLatLongs = data.split(" || ");
totalcount = 0;
for(x in theLatLongs){
var theLatLong = "";
var latLong = theLatLongs[x].substr(1);
var latLong = latLong.slice(0, -1);
var theLatLong = latLong.split(", ");
var thelat = theLatLong[0];
var thelong = theLatLong[1];
totalcount = totalcount+1;
}
$('#totalcount').html('<h6><span>'+totalcount+'</span> Households found</h6>Filtered by location');
});
It all works fine (I think). It's just incredibly slow. I know facebook have much better resources, but there create advert filterer is amazingly quick. I will also be implementing further filters. I tried a join but the time difference didn't seem to massive. Sometimes it doesn't even return results at all and crashes my mysql service...
there are 3 sources that can slow the code: mysql, php, js.
the first thing I would do is run the sql (the join version), in a tool like toad or do a php file that outputs the raw result. You can add console.time/console.timeEnd to js, and mictrotime in php.
another "fast and dirty" check is to past "your_server"/php/properties.php?bounds=YourBounds,
and check the result. it will give you some indication.
If you are certain it's sql, try to index digital_hub.address_list.postcodes, postcode.postcodeGoogle.lat, and postcode.postcodeGoogle.long.
Then, in your php "raw" script (or your sql tool), try to call the query with less column,
or even with "select count(*)". If the "select count(*)" is way faster, that means that the returning value is slowing the system. This is typical of empty (non null) date fields by example.
But they key is simple, time the different parts of the process to isolate the bottleneck.
console.time('load');
$.get("php/properties.php?bounds="+bounds, function(data){
console.timeEnd('load');
console.time('parse');
var theLatLongs = data.split(" || ");
totalcount = 0;
for(x in theLatLong ){
var theLatLong = "";
var latLong = theLatLongs[x].substr(1);
var latLong = latLong.slice(0, -1);
var theLatLong = latLong.split(", ");
var thelat = theLatLong[0];
var thelong = theLatLong[1];
totalcount = totalcount+1;
}
console.timeEnd('parse');
console.time('display');
$('#totalcount').html('<h6><span>'+totalcount+'</span> Households found</h6>Filtered by location');
console.timeEnd('display');
});
on a side note, you might consider json data. (and review your use of thelatlong js var, but I guess you are debugging)
in php:
while ($row = msqlqresult) {
$resultArray[] = $row;
}
$resultJson = json_encode($resultArray);
in js:
console.time('load');
$.getJSON("php/properties.php", {bounds: bounds}, function(data){
console.timeEnd('load');
console.time('parse');
totalcount = 0;
for(var x in data){
var thelat = theLatLong[x].lat;
var thelong = theLatLong[x].long;
totalcount = totalcount+1;
}
console.timeEnd('parse');
console.time('display');
$('#totalcount').html('<h6><span>'+totalcount+'</span> Households found</h6>Filtered by location');
console.timeEnd('display');
});

problem with jquery autocomplete and mySql

search.php
$text = $mysqli->$_POST['term'];
$query = "SELECT name FROM males WHERE name LIKE '%" . $text . "%' ORDER BY name ASC";
$result = $mysqli->query($query);
$json = '[';
$first = true;
while($row = $result->fetch_assoc())
{
if (!$first) { $json .= ','; } else { $first = false; }
$json .= '{"value":"'.$row['name'].'"}';
}
$json .= ']';
echo $json;
index.php
1) HTML
<body>
Text: <input type="text" id="autocomplete" />
</body>
2) jQuery
$( "#autocomplete" ).autocomplete({
source: function(request, response) {
$.ajax({ url: "http://localhost/testing/auto/search.php",
data: { term: $("#autocomplete").val()},
dataType: "json",
type: "POST",
success: function(data){
response(data);
}
});
},
minLength: 2
});
When I type 2 letters, it gives me all the names in my database even if these two letters do not match any of the names.
How does that happen and how do I fix it?
Looks like my comment worked as an answer, hence this answer.
What does $mysqli->$_POST['term'] do? I think you should have $text = $_POST['term'];. This should work.
Change the PHP to
$text = $_POST['term'];
$query = "SELECT name FROM males WHERE name LIKE '%" . $mysqli->real_escape_string($text) . "%' ORDER BY name ASC";
$result = $mysqli->query($query);
echo json_encode($result->fetch_all(MYSQLI_ASSOC));
You forgot to escape the input to prevent SQL injections. Additionally, use #mu's answer to fix your front-end code.
Your source callback isn't doing what you think it is. The current contents of the autocompleter are in request.term, not in $("#autocomplete").val(). You're sending an empty value for term back to your PHP and then your SQL looks like:
SELECT name FROM males WHERE name LIKE '%%' ORDER BY name ASC
which of courses matches everything in your males table. Your source callback should look like this:
source: function(request, response) {
$.ajax({
url: "http://localhost/testing/auto/search.php",
data: { term: request.term },
dataType: "json",
type: "POST",
success: function(data) {
response(data);
}
});
}
The jQuery-UI widget probably manipulates the DOM a fair bit so the #autocomplete input element may not have anything useful in it until the autocompleter has a final value for it.
For reference, here's what the fine manual has to say:
The third variation, the callback, provides the most flexibility, and can be used to connect any data source to Autocomplete. The callback gets two arguments:
A request object, with a single property called term, which refers to the value currently in the text input. For example, when the user entered "new yo" in a city field, the Autocomplete term will equal "new yo".
First make sure that your search.php is working. Switch to $_GET['term'] and run the page directly until you get the data you wanted.
I would personally change the query from from LIKE '%text%' to LIKE 'text%'.
After that use Firebug to examine the parameters that are transferred to the search.php with an AJAX call. BTW, are you sure that your jquery code is correct?
I think is your sql query. U were using
$query = "SELECT name FROM males WHERE name LIKE '%$text%' ORDER BY name ASC"
if your name list like
Aaron
Alexander
Maartha
...
If you type 'AA', the above query will result : Aaron, Maartha. Because the query will search matching given string between the whole strings.
% text % means the query result will ignore the left and right result.
if you're looking for names field data you supposed to use query
$query = "SELECT name FROM males WHERE name LIKE '$text%' ORDER BY name ASC"
If you type 'AA, it will result : Aaron.
Note that jQuery only returns what you're asking to the database.
Use $_REQUEST['term'] instead $_POST['term'].

help with chained selects and existing form values, ex: adding <option selected="selected"></option>

I have a 3 step chained-select sequence, game -> battle -> winning side , which pulls all data from a MySQL database.
After some wandering on the internet, I found a compact jQuery script that performs wonderfully. However, I am at a loss as to how to allow for existing data: <option selected="selected"></option> using this script.
chained select javascript:
<script>
var ajax = new Array();
function getScenNumList(sel)
{
var game = sel.options[sel.selectedIndex].value;
document.getElementById('scenarioNumber').options.length = 0; // Empty scenario number select box
if(game.length>0){
var index = ajax.length;
ajax[index] = new sack();
ajax[index].requestFile = 'js/getPlayData.php?gameName='+game; // Specifying which file to get
ajax[index].onCompletion = function(){ createScenarioNumbers(index) }; // Specify function that will be executed after file has been found
ajax[index].runAJAX(); // Execute AJAX function
}
}
function createScenarioNumbers(index)
{
var obj = document.getElementById('scenarioNumber');
eval(ajax[index].response); // Executing the response from Ajax as Javascript code
}
function getNations(sel)
{
var scenNum = sel.options[sel.selectedIndex].value;
document.getElementById('victor').options.length = 0; // Empty nation select box
if(scenNum.length>0){
var index = ajax.length;
ajax[index] = new sack();
ajax[index].requestFile = 'js/getPlayData.php?scenID='+scenNum; // Specifying which file to get
ajax[index].onCompletion = function(){ createNations(index) }; // Specify function that will be executed after file has been found
ajax[index].runAJAX(); // Execute AJAX function
}
}
function createNations(index)
{
var obj = document.getElementById('victor');
eval(ajax[index].response); // Executing the response from Ajax as Javascript code
}
</script>
excerpt from the PHP database retrieval script (getPlayData.php):
$gameName = mysql_real_escape_string($_GET['gameName']);
$q = "SELECT a, b, c FROM table WHERE game='$gameName' ORDER BY num ASC";
$r = mysql_query($q);
echo "obj.options[obj.options.length] = new Option('#','');\n";
while ($row = mysql_fetch_row($r)) {
$string = mysql_real_escape_string(($row[0].' - '.$row[1])); // needed so quotes ' " don't break the javascript
echo "obj.options[obj.options.length] = new Option('$string','$row[2]');\n";
}
echoing the obj.options is the stock method this script was using. It seems ugly to me, but I don't know any javascript so I didn't want to fiddle with it.
The HTML is simple enough, just a table with a few empty <select> objects with IDs matching those in the javascript and onchange="getXXX(this)" calls.
My question is this: Everything works great for new records, but I'm at a loss as to how I can alter this to support marking one option from each select as selected, assuming I have that data in hand (ex: a user is editing an existing record) ?
Many thanks!
You can see this tutorial for creating an option that is selected as default. http://www.javascriptkit.com/javatutors/selectcontent.shtml One parameter in the option constructor dictate that whether the option is selected or not.
In the PHP file you will edit as follow:
$gameName = mysql_real_escape_string($_GET['gameName']);
$q = "SELECT a, b, c FROM table WHERE game='$gameName' ORDER BY num ASC";
$r = mysql_query($q);
echo "obj.options[obj.options.length] = new Option('#','');\n";
while ($row = mysql_fetch_row($r)) {
$string = mysql_real_escape_string(($row[0].' - '.$row[1])); // needed so quotes ' " don't break the javascript
if ($string ......)
echo "obj.options[obj.options.length] = new Option('$string','$row[2]', false, true);\n";
else
......
}

Categories