Code Igniter - not showing the entry I need - mysql

I have the following code to get one line for each MAC with the LATEST state. The problem I have is that I get one line but not with the latest state but rather with the earliest.
function get_active_devices($min_duration, $max_duration)
{
//get all active devices DESC order
$this->db->distinct();
$this->db->group_by('mac');
$this->db->order_by("id", "desc");
$this->db->select('data.mac, state, time, iot_bo.notified, iot_bo.op_state, iot_bo.Name');
$this->db->where('time >', time()-$max_duration);
$this->db->where('time <', time()-$min_duration);
$this->db->join('iot_bo', 'iot_bo.mac = data.mac');
$this->db->where('iot_bo.op_state', '1');
$query = $this->db->get();
return $query;
}

Have you tried the query without the distinct and groupBy first? May be the result you want isn't in the total result set to begin with. Because there doesn't seem to be anything wrong with your use of db methods as it is.

Related

MySQL - Using LIKE ? With Multiple Columns Search

I've had a look around Stackoverflow and can't seem to find what I am looking for.
I have a dynamically updating AJAX search form which shows location data from database.
The issue I am having is with this query here:
$sql = "SELECT location FROM location_data WHERE location LIKE ? LIMIT 10";
Let me explain what is happening first. There are 3 different columns in a database table, one called location, one called CRS and one called tiploc.
I would like to display results like the following:
Select location FROM location_data WHERE location(textbox) is LIKE ?(what the person typed in) OR CRS is LIKE ? or TIPLOC is LIKE ?
Now i've only tried it with CRS so far, and ive done the following query:
$sql = "SELECT location FROM location_data WHERE location OR CRS LIKE ? LIMIT 10";
The above only displays the CRS result (exact match) and doesn't provide any suggestions for location, only shows CRS. Does anyone know how I can amend my query, so that it searches both location and CRS and TIPLOC, LIKE on location, but exact match only on CRS and TIPLOC?
if(isset($_REQUEST['term'])){
// Prepare a select statement
$sql = "SELECT location FROM location_data WHERE location LIKE ? LIMIT 10";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_term);
// Set parameters
$param_term = $_REQUEST['term'] . '%';
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
$result = mysqli_stmt_get_result($stmt);
// Check number of rows in the result set
if(mysqli_num_rows($result) > 0){
// Fetch result rows as an associative array
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
echo "<p>" . $row["location"] . "</p>";
}
} else{
echo "<p>No matches found</p>";
}
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// close connection
mysqli_close($link);
Now heres the on page search, the field I am pulling input from is called "location".
--Code for JS AJAX Search--
<script type="text/javascript">
$(document).ready(function(){
$('.search-box input[type="text"]').on("keyup input", function(){
/* Get input value on change */
$(".result").show();
var inputVal = $(this).val();
var resultDropdown = $(this).siblings(".result");
if(inputVal.length >2){
$.get("backend-search.php", {term: inputVal}).done(function(data){
// Display the returned data in browser
resultDropdown.html(data);
});
} else{
resultDropdown.empty();
}
});
// Set search input value on click of result item
$(document).on("click", ".result p", function(){
$(this).parents(".search-box").find('input[type="text"]').val($(this).text());
$(this).parent(".result").empty();
});
});
$(document).click(function(){
$(".result").hide();
});
</script>
You need to repeat the LIKE expression for each column.
$sql = "SELECT location
FROM location_data
WHERE location LIKE ? OR CRS LIKE ? OR TIPLOC LIKE ?
LIMIT 10";
And since there are now 3 placeholders in the query, you need to fill them all in with the binding:
mysqli_stmt_bind_param($stmt, "sss", $param_term, $param_term, $param_term);
For every individual expression in OR, you have to specify their comparison conditions. Note the location LIKE ? instead of LOCATION OR:
$sql = "SELECT location
FROM location_data
WHERE location LIKE ?
OR CRS LIKE ?
OR TIPLOC LIKE ?
LIMIT 10";
Note: LIMIT clause without ORDER BY is non-deterministic in nature, since MySQL stores an unordered dataset. It basically means that, any 10 rows can be returned by MySQL (if not using ORDER BY).

How to get random row from MYSQL and how to write it in active records?

This is my query
"SELECT * FROM package_info ORDER BY RAND() LIMIT 0,3;"
I try to write it in active records like this.
$this->db->select('*');
$this->db->from('package_info');
$this->db->order_by("id", "random");
$this->db->limit(0, 3);
$result = $this->db->get();
But it is not work. How to write this in active record?
Use Below code it will work fine -
$this->db->select('*');
$this->db->from('package_info');
$this->db->order_by("id", "random");
$this->db->limit(3, 0);
$result = $this->db->get()->result();
// shows last executed query
echo $this->db->last_query();
// shows data fetched
echo "<pre>";
print_r( $result );
echo "</pre>";
You can visit on this link to view how queries are used in Codeigniter.
https://www.codeigniter.com/userguide2/database/active_record.html
CodeIgniter does not mandate that you provide 2 arguments for most Query Builder statements, you can do a whole WHERE by doing ->where('1=1') and its perfectly fine.
I'm surprised how many people don't understand method chaining, but I'll show it in my example it is just nicer...
$result = $this->db->select('*')
->from('package_info')
->order_by('rand()')
->limit(0, 3)
>get();
As per above, if you don't have 2 parameters in your original query, dont feel compelled to add two.
Another thing you can do with basic queries like these, is omit the from('package_info') entirely and stick the table name in the ->get('package_info')
If you cant be bothered with query builder you don't need to use it either. I don't for some things (you cannot use UNION with them for one). In this case just use
$result = $this->db->query("SELECT * FROM package_info ORDER BY RAND() LIMIT 0,3;");

Webmatrix if statement issues. any ideas?

I have written a SQL query, which extracts the lowest weekly price for a property stored in my database:
var rPropertyId = Request.QueryString["PropertyID"];
var cheapestrate = "SELECT TOP 1 * FROM RateInfo WHERE PropertyID=#0 ORDER BY RateWeekly ASC";
var qcheapestrate = db.QuerySingle (cheapestrate, rPropertyId);
I'm pretty confident that this statement is correct. The problem i have, is that not ALL propertys have pricing, so i only want to show this price if they do. I have created the below if statement, but it's telling me i'm missing an ; somewhere?
#if(qcheapestrate=!null){
Rates From qcheapestrate.rateweekly per week
}
So i'm trying to check if the query returns an entry. if it does, i want to show the lowest "rateweekly" value. Hopefully this all makes sense!
Try this...
#if(qcheapestrate!=null){
<text>Rates From</text>
#qcheapestrate.rateweekly
<text>per week</text>
}

Laravel - How to paginate here?

I have this code and I want to paginate $shares.
How can I archive this?
$level = Share::join('follows', 'shares.user_id', '=', 'follows.user_id')
->where('follows.follower_id', Auth::user()->id)
->where('follows.level', 1)
->get(array('shares.*'));
//get 10% of shares
$count = Share::count()/10;
$count = round($count);
$top10 = Share::orderBy('positive', 'DESC')
->take($count)
->get();
$shares = $top10->merge($level);
//get only unique from shares
$unique = array();
$uniqueShares = $shares->filter(function($item) use (&$unique) {
if (!in_array($item->id, $unique)) {
$unique[] = $item->id;
return true;
} else {
return false;
}
});
//order by id
$shares = $uniqueShares->sortBy(function($share)
{
return -($share->id);
});
return View::make('layout/main')
->with('shares', $shares);
lots of reudandant unnecessary codes here.
1st:
$level = Share::join('follows', 'shares.user_id', '=', 'follows.user_id')
->where('follows.follower_id', Auth::user()->id)
->where('follows.level', 1)
->get(array('shares.*'));
Why you are taking ALL the records only to discard it later?
2nd:
$shares = $top10->merge($level); Why you are merging the two arrays?
3rd:
$uniqueShares = $shares->filter(function($item) use (&$unique) {
if (!in_array($item->id, $unique)) {
$unique[] = $item->id;
return true;
} else {
return false;
}
});
You HAD to wrote this snippet because above in 2nd, you merged the two arrays which will yield duplicated entries. So why merging?
4th:
//order by id
$shares = $uniqueShares->sortBy(function($share)
{
return -($share->id);
});
And here comes the actual data which you actually want.
So let's recape
You need
10% of total shares
order by some positive column
order by amount of shares perhaps as i am guessing.
To use the inbuilt paginate(), you'l need paginate() that's a must.
Rest is simple.
count the total result. round(Share::count()/10)
put it in paginate() as the 1st arguement.
Add the order by clause whichever is necessary.
looking at the code, it doesn't look like you will/should have duplicated data which may haved added the distinct and group by clause.
use remember in Share::count()/10; to Cache it. You don't need to run the query over and over again.
and you're done.
The way you are merging your queries you may need to manually create it the pagination in your blade, then send a variable to "take" the next set you want.
Read the Laravel Docs for more info on implementing it into your views and manually creating it.
http://laravel.com/docs/pagination
Try this, should be good to go
Share::join('follows', 'shares.user_id', '=', 'follows.user_id')
->where('follows.follower_id', Auth::user()->id)
->where('follows.level', 1)
->paginate(20);
Maybe you would like to specify columns to select in select() method.

mySQL insert HTML form posting problem on results... Need help

I am stumped!! I can't figure this out.
I created an HTML form that inserts a record into mySQL. It works and I can see the new records I add/insert. BUT, I get the wrong confirmation page: I get a the FAIL PAGE instead of the SUCCESS page. I see the new record but I always get taken to the fail page. Why?
Is there something wrong with the script or a setting inside mySQL?
Here is my form post script:
<?
$host="XXXXXXXXXXXX";
$username="XXXXXXXX";
$password="XXXXXXXX";
$db_name="XXXXXXXXX";
$tbl_name="cartons_current";
mysql_connect("$host", "$username", "$password") or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
$order = "INSERT INTO cartons_current (type, part_no, description, count,
size, min, max, qty)
VALUES
('$_POST[type]', '$_POST[part_no]', '$_POST[description]', '$_POST[count]',
'$_POST[size]', '$_POST[min]', '$_POST[max]', '$_POST[qty]')";
$result = mysql_query($order);
$result = mysql_query($order); //order executes
if ($result) {
$part_no = $_REQUEST['part_no'] ;
header("location: inv_fc_result_new_success.php?part_no=" . urlencode($part_no));
}
else {
header("location: inv_fc_result_new_fail.php");
}
?>
Your code looks OK, except for the possibility that mysql_query() gets called twice. If that is actual code, then I suspect the first call loads the record you are seeing, and the subsequent call returns the error message.
$result = mysql_query($order);
$result = mysql_query($order); //order executes
You appear to be calling mysql_query twice. If it's not a typo in copying the code onto stackoverflow then this could be the issue.
The first call is returning true but second call is returning 'false' hence the fail page is displayed